update
This commit is contained in:
@@ -0,0 +1,202 @@
|
||||
<?php
|
||||
/**
|
||||
* Class Google\Site_Kit\Modules\Analytics_4\AMP_Tag
|
||||
*
|
||||
* @package Google\Site_Kit\Modules\Analytics_4
|
||||
* @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;
|
||||
|
||||
use Google\Site_Kit\Core\Modules\Tags\Module_AMP_Tag;
|
||||
use Google\Site_Kit\Core\Tags\Tag_With_Linker_Interface;
|
||||
use Google\Site_Kit\Core\Util\Method_Proxy_Trait;
|
||||
use Google\Site_Kit\Core\Tags\Tag_With_Linker_Trait;
|
||||
|
||||
/**
|
||||
* Class for AMP tag.
|
||||
*
|
||||
* @since 1.104.0
|
||||
* @access private
|
||||
* @ignore
|
||||
*/
|
||||
class AMP_Tag extends Module_AMP_Tag implements Tag_Interface, Tag_With_Linker_Interface {
|
||||
|
||||
use Method_Proxy_Trait, Tag_With_Linker_Trait;
|
||||
|
||||
/**
|
||||
* Custom dimensions data.
|
||||
*
|
||||
* @since 1.113.0
|
||||
* @var array
|
||||
*/
|
||||
private $custom_dimensions;
|
||||
|
||||
/**
|
||||
* Ads conversion ID.
|
||||
*
|
||||
* @since 1.118.0
|
||||
* @var string
|
||||
*/
|
||||
private $ads_conversion_id;
|
||||
|
||||
/**
|
||||
* Sets the current home domain.
|
||||
*
|
||||
* @since 1.118.0
|
||||
*
|
||||
* @param string $domain Domain name.
|
||||
*/
|
||||
public function set_home_domain( $domain ) {
|
||||
$this->home_domain = $domain;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the ads conversion ID.
|
||||
*
|
||||
* @since 1.32.0
|
||||
*
|
||||
* @param string $ads_conversion_id Ads ID.
|
||||
*/
|
||||
public function set_ads_conversion_id( $ads_conversion_id ) {
|
||||
$this->ads_conversion_id = $ads_conversion_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets custom dimensions data.
|
||||
*
|
||||
* @since 1.113.0
|
||||
*
|
||||
* @param string $custom_dimensions Custom dimensions data.
|
||||
*/
|
||||
public function set_custom_dimensions( $custom_dimensions ) {
|
||||
$this->custom_dimensions = $custom_dimensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers tag hooks.
|
||||
*
|
||||
* @since 1.104.0
|
||||
*/
|
||||
public function register() {
|
||||
$render = $this->get_method_proxy_once( 'render' );
|
||||
|
||||
// Which actions are run depends on the version of the AMP Plugin
|
||||
// (https://amp-wp.org/) available. Version >=1.3 exposes a
|
||||
// new, `amp_print_analytics` action.
|
||||
// For all AMP modes, AMP plugin version >=1.3.
|
||||
add_action( 'amp_print_analytics', $render );
|
||||
// For AMP Standard and Transitional, AMP plugin version <1.3.
|
||||
add_action( 'wp_footer', $render, 20 );
|
||||
// For AMP Reader, AMP plugin version <1.3.
|
||||
add_action( 'amp_post_template_footer', $render, 20 );
|
||||
// For Web Stories plugin.
|
||||
add_action( 'web_stories_print_analytics', $render );
|
||||
|
||||
// Load amp-analytics component for AMP Reader.
|
||||
$this->enqueue_amp_reader_component_script( 'amp-analytics', 'https://cdn.ampproject.org/v0/amp-analytics-0.1.js' );
|
||||
|
||||
$this->do_init_tag_action();
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs gtag <amp-analytics> tag.
|
||||
*
|
||||
* @since 1.104.0
|
||||
*/
|
||||
protected function render() {
|
||||
$config = $this->get_tag_config();
|
||||
|
||||
if ( ! empty( $this->ads_conversion_id ) ) {
|
||||
$config[ $this->ads_conversion_id ] = array(
|
||||
'groups' => 'default',
|
||||
);
|
||||
}
|
||||
|
||||
$gtag_amp_opt = array(
|
||||
'optoutElementId' => '__gaOptOutExtension',
|
||||
'vars' => array(
|
||||
'gtag_id' => $this->tag_id,
|
||||
'config' => $config,
|
||||
),
|
||||
);
|
||||
|
||||
/**
|
||||
* Filters the gtag configuration options for the amp-analytics tag.
|
||||
*
|
||||
* You can use the {@see 'googlesitekit_gtag_opt'} filter to do the same for gtag in non-AMP.
|
||||
*
|
||||
* @since 1.24.0
|
||||
* @see https://developers.google.com/gtagjs/devguide/amp
|
||||
*
|
||||
* @param array $gtag_amp_opt gtag config options for AMP.
|
||||
*/
|
||||
$gtag_amp_opt_filtered = apply_filters( 'googlesitekit_amp_gtag_opt', $gtag_amp_opt );
|
||||
|
||||
// Ensure gtag_id is set to the correct value.
|
||||
if ( ! is_array( $gtag_amp_opt_filtered ) ) {
|
||||
$gtag_amp_opt_filtered = $gtag_amp_opt;
|
||||
}
|
||||
|
||||
if ( ! isset( $gtag_amp_opt_filtered['vars'] ) || ! is_array( $gtag_amp_opt_filtered['vars'] ) ) {
|
||||
$gtag_amp_opt_filtered['vars'] = $gtag_amp_opt['vars'];
|
||||
}
|
||||
|
||||
printf( "\n<!-- %s -->\n", esc_html__( 'Google Analytics AMP snippet added by Site Kit', 'google-site-kit' ) );
|
||||
|
||||
printf(
|
||||
'<amp-analytics type="gtag" data-credentials="include"%s><script type="application/json">%s</script></amp-analytics>',
|
||||
$this->get_tag_blocked_on_consent_attribute(), // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
wp_json_encode( $gtag_amp_opt_filtered )
|
||||
);
|
||||
|
||||
printf( "\n<!-- %s -->\n", esc_html__( 'End Google Analytics AMP snippet added by Site Kit', 'google-site-kit' ) );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Extends gtag vars config with the GA4 tag config.
|
||||
*
|
||||
* @since 1.104.0
|
||||
*
|
||||
* @param array $opt AMP gtag config.
|
||||
* @return array
|
||||
*/
|
||||
protected function extend_gtag_opt( $opt ) {
|
||||
$opt['vars']['config'] = array_merge(
|
||||
$opt['vars']['config'],
|
||||
$this->get_tag_config()
|
||||
);
|
||||
// `gtag_id` isn't used in a multi-destination configuration.
|
||||
// See https://developers.google.com/analytics/devguides/collection/amp-analytics/#sending_data_to_multiple_destinations.
|
||||
unset( $opt['vars']['gtag_id'] );
|
||||
|
||||
return $opt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the tag config as used in the gtag data vars.
|
||||
*
|
||||
* @since 1.113.0
|
||||
*
|
||||
* @return array Tag configuration.
|
||||
*/
|
||||
protected function get_tag_config() {
|
||||
$config = array(
|
||||
$this->tag_id => array(
|
||||
'groups' => 'default',
|
||||
),
|
||||
);
|
||||
|
||||
if ( ! empty( $this->custom_dimensions ) ) {
|
||||
$config[ $this->tag_id ] = array_merge(
|
||||
$config[ $this->tag_id ],
|
||||
$this->custom_dimensions
|
||||
);
|
||||
}
|
||||
|
||||
return $this->add_linker_to_tag_config( $config );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
<?php
|
||||
/**
|
||||
* Class Google\Site_Kit\Modules\Analytics_4\Account_Ticket
|
||||
*
|
||||
* @package Google\Site_Kit
|
||||
* @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;
|
||||
|
||||
/**
|
||||
* Class representing an account ticket for Analytics 4 account provisioning with associated parameters.
|
||||
*
|
||||
* @since 1.98.0
|
||||
* @access private
|
||||
* @ignore
|
||||
*/
|
||||
class Account_Ticket {
|
||||
|
||||
/**
|
||||
* Account ticket ID.
|
||||
*
|
||||
* @since 1.98.0
|
||||
* @var string
|
||||
*/
|
||||
protected $id;
|
||||
|
||||
/**
|
||||
* Property name.
|
||||
*
|
||||
* @since 1.98.0
|
||||
* @var string
|
||||
*/
|
||||
protected $property_name;
|
||||
|
||||
/**
|
||||
* Data stream name.
|
||||
*
|
||||
* @since 1.98.0
|
||||
* @var string
|
||||
*/
|
||||
protected $data_stream_name;
|
||||
|
||||
/**
|
||||
* Timezone.
|
||||
*
|
||||
* @since 1.98.0
|
||||
* @var string
|
||||
*/
|
||||
protected $timezone;
|
||||
|
||||
/**
|
||||
* Whether or not enhanced measurement should be enabled.
|
||||
*
|
||||
* @since 1.111.0
|
||||
* @var boolean
|
||||
*/
|
||||
protected $enhanced_measurement_stream_enabled;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @since 1.98.0
|
||||
*
|
||||
* @param array $data Data to hydrate properties with.
|
||||
*/
|
||||
public function __construct( $data = null ) {
|
||||
if ( ! is_array( $data ) ) {
|
||||
return;
|
||||
}
|
||||
foreach ( $data as $key => $value ) {
|
||||
if ( property_exists( $this, $key ) ) {
|
||||
$this->{"set_$key"}( $value );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the account ticket ID.
|
||||
*
|
||||
* @since 1.98.0
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_id() {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the account ticket ID.
|
||||
*
|
||||
* @since 1.98.0
|
||||
*
|
||||
* @param string $id Account ticket ID.
|
||||
*/
|
||||
public function set_id( $id ) {
|
||||
$this->id = (string) $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the property name.
|
||||
*
|
||||
* @since 1.98.0
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_property_name() {
|
||||
return $this->property_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the property name.
|
||||
*
|
||||
* @since 1.98.0
|
||||
*
|
||||
* @param string $property_name Property name.
|
||||
*/
|
||||
public function set_property_name( $property_name ) {
|
||||
$this->property_name = (string) $property_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the data stream name.
|
||||
*
|
||||
* @since 1.98.0
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_data_stream_name() {
|
||||
return $this->data_stream_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the data stream name.
|
||||
*
|
||||
* @since 1.98.0
|
||||
*
|
||||
* @param string $data_stream_name Data stream name.
|
||||
*/
|
||||
public function set_data_stream_name( $data_stream_name ) {
|
||||
$this->data_stream_name = (string) $data_stream_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the timezone.
|
||||
*
|
||||
* @since 1.98.0
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_timezone() {
|
||||
return $this->timezone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the timezone.
|
||||
*
|
||||
* @since 1.98.0
|
||||
*
|
||||
* @param string $timezone Timezone.
|
||||
*/
|
||||
public function set_timezone( $timezone ) {
|
||||
$this->timezone = (string) $timezone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the enabled state of enhanced measurement for the data stream.
|
||||
*
|
||||
* @since 1.111.0
|
||||
*
|
||||
* @return bool $enabled Enabled state.
|
||||
*/
|
||||
public function get_enhanced_measurement_stream_enabled() {
|
||||
return $this->enhanced_measurement_stream_enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the enabled state of enhanced measurement for the data stream.
|
||||
*
|
||||
* @since 1.111.0
|
||||
*
|
||||
* @param bool $enabled Enabled state.
|
||||
*/
|
||||
public function set_enhanced_measurement_stream_enabled( $enabled ) {
|
||||
$this->enhanced_measurement_stream_enabled = (bool) $enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the array representation of the instance values.
|
||||
*
|
||||
* @since 1.98.0
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function to_array() {
|
||||
return get_object_vars( $this );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
<?php
|
||||
/**
|
||||
* Class Google\Site_Kit\Modules\Analytics_4\Advanced_Tracking
|
||||
*
|
||||
* @package Google\Site_Kit\Modules\Analytics_4
|
||||
* @copyright 2024 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;
|
||||
|
||||
use Google\Site_Kit\Context;
|
||||
use Google\Site_Kit\Modules\Analytics_4\Advanced_Tracking\Event_List;
|
||||
use Google\Site_Kit\Modules\Analytics_4\Advanced_Tracking\Script_Injector;
|
||||
use Google\Site_Kit\Modules\Analytics_4\Advanced_Tracking\AMP_Config_Injector;
|
||||
use Google\Site_Kit\Modules\Analytics_4\Advanced_Tracking\Event_List_Registry;
|
||||
use Google\Site_Kit\Modules\Analytics_4;
|
||||
|
||||
/**
|
||||
* Class for Google Analytics Advanced Event Tracking.
|
||||
*
|
||||
* @since 1.18.0.
|
||||
* @since 1.121.0 Migrated from the Analytics (UA) namespace.
|
||||
* @access private
|
||||
* @ignore
|
||||
*/
|
||||
final class Advanced_Tracking {
|
||||
|
||||
/**
|
||||
* Plugin context.
|
||||
*
|
||||
* @since 1.18.0.
|
||||
* @var Context
|
||||
*/
|
||||
protected $context;
|
||||
|
||||
/**
|
||||
* Map of events to be tracked.
|
||||
*
|
||||
* @since 1.18.0.
|
||||
* @var array Map of Event instances, keyed by their unique ID.
|
||||
*/
|
||||
private $events;
|
||||
|
||||
/**
|
||||
* Main class event list registry instance.
|
||||
*
|
||||
* @since 1.18.0.
|
||||
* @var Event_List_Registry
|
||||
*/
|
||||
private $event_list_registry;
|
||||
|
||||
/**
|
||||
* Advanced_Tracking constructor.
|
||||
*
|
||||
* @since 1.18.0.
|
||||
*
|
||||
* @param Context $context Plugin context.
|
||||
*/
|
||||
public function __construct( Context $context ) {
|
||||
$this->context = $context;
|
||||
$this->event_list_registry = new Event_List_Registry();
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers functionality through WordPress hooks.
|
||||
*
|
||||
* @since 1.18.0.
|
||||
* @since 1.118.0 Renamed hooks to target Analytics 4 module.
|
||||
*/
|
||||
public function register() {
|
||||
$slug_name = Analytics_4::MODULE_SLUG;
|
||||
|
||||
add_action(
|
||||
"googlesitekit_{$slug_name}_init_tag",
|
||||
function() {
|
||||
$this->register_event_lists();
|
||||
add_action(
|
||||
'wp_footer',
|
||||
function() {
|
||||
$this->set_up_advanced_tracking();
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
add_action(
|
||||
"googlesitekit_{$slug_name}_init_tag_amp",
|
||||
function() {
|
||||
$this->register_event_lists();
|
||||
add_filter(
|
||||
'googlesitekit_amp_gtag_opt',
|
||||
function( $gtag_amp_opt ) {
|
||||
return $this->set_up_advanced_tracking_amp( $gtag_amp_opt );
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the map of unique events.
|
||||
*
|
||||
* @since 1.18.0.
|
||||
*
|
||||
* @return array Map of Event instances, keyed by their unique ID.
|
||||
*/
|
||||
public function get_events() {
|
||||
return $this->events;
|
||||
}
|
||||
|
||||
/**
|
||||
* Injects javascript to track active events.
|
||||
*
|
||||
* @since 1.18.0.
|
||||
*/
|
||||
private function set_up_advanced_tracking() {
|
||||
$this->compile_events();
|
||||
( new Script_Injector( $this->context ) )->inject_event_script( $this->events );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds triggers to AMP configuration.
|
||||
*
|
||||
* @since 1.18.0.
|
||||
*
|
||||
* @param array $gtag_amp_opt gtag config options for AMP.
|
||||
* @return array Filtered $gtag_amp_opt.
|
||||
*/
|
||||
private function set_up_advanced_tracking_amp( $gtag_amp_opt ) {
|
||||
$this->compile_events();
|
||||
return ( new AMP_Config_Injector() )->inject_event_configurations( $gtag_amp_opt, $this->events );
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates and registers event lists.
|
||||
*
|
||||
* @since 1.18.0.
|
||||
*/
|
||||
private function register_event_lists() {
|
||||
/**
|
||||
* Fires when the Advanced_Tracking class is ready to receive event lists.
|
||||
*
|
||||
* This means that Advanced_Tracking class stores the event lists in the Event_List_Registry instance.
|
||||
*
|
||||
* @since 1.18.0.
|
||||
*
|
||||
* @param Event_List_Registry $event_list_registry
|
||||
*/
|
||||
do_action( 'googlesitekit_analytics_register_event_lists', $this->event_list_registry );
|
||||
|
||||
foreach ( $this->event_list_registry->get_lists() as $event_list ) {
|
||||
$event_list->register();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the list of Event objects.
|
||||
*
|
||||
* @since 1.18.0.
|
||||
*/
|
||||
private function compile_events() {
|
||||
$this->events = array_reduce(
|
||||
$this->event_list_registry->get_lists(),
|
||||
function ( $events, Event_List $event_list ) {
|
||||
return array_merge( $events, $event_list->get_events() );
|
||||
},
|
||||
array()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
/**
|
||||
* Class Google\Site_Kit\Modules\Analytics_4\Advanced_Tracking\AMP_Config_Injector
|
||||
*
|
||||
* @package Google\Site_Kit\Modules\Analytics_4
|
||||
* @copyright 2024 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\Advanced_Tracking;
|
||||
|
||||
/**
|
||||
* Class for injecting JavaScript based on the registered event configurations.
|
||||
*
|
||||
* @since 1.18.0.
|
||||
* @access private
|
||||
* @ignore
|
||||
*/
|
||||
final class AMP_Config_Injector {
|
||||
|
||||
/**
|
||||
* Creates list of measurement event configurations and javascript to inject.
|
||||
*
|
||||
* @since 1.18.0.
|
||||
* @since 1.121.0 Migrated from the Analytics (UA) namespace.
|
||||
*
|
||||
* @param array $gtag_amp_opt gtag config options for AMP.
|
||||
* @param array $events The map of Event objects, keyed by their unique ID.
|
||||
* @return array Filtered $gtag_amp_opt.
|
||||
*/
|
||||
public function inject_event_configurations( $gtag_amp_opt, $events ) {
|
||||
if ( empty( $events ) ) {
|
||||
return $gtag_amp_opt;
|
||||
}
|
||||
|
||||
if ( ! array_key_exists( 'triggers', $gtag_amp_opt ) ) {
|
||||
$gtag_amp_opt['triggers'] = array();
|
||||
}
|
||||
|
||||
foreach ( $events as $amp_trigger_key => $event ) {
|
||||
$event_config = $event->get_config();
|
||||
|
||||
$amp_trigger = array();
|
||||
if ( 'DOMContentLoaded' === $event_config['on'] ) {
|
||||
$amp_trigger['on'] = 'visible';
|
||||
} else {
|
||||
$amp_trigger['on'] = $event_config['on'];
|
||||
$amp_trigger['selector'] = $event_config['selector'];
|
||||
}
|
||||
|
||||
$amp_trigger['vars'] = array();
|
||||
$amp_trigger['vars']['event_name'] = $event_config['action'];
|
||||
if ( is_array( $event_config['metadata'] ) ) {
|
||||
foreach ( $event_config['metadata'] as $key => $value ) {
|
||||
$amp_trigger['vars'][ $key ] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
$gtag_amp_opt['triggers'][ $amp_trigger_key ] = $amp_trigger;
|
||||
}
|
||||
|
||||
return $gtag_amp_opt;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
/**
|
||||
* Class Google\Site_Kit\Modules\Analytics_4\Advanced_Tracking\Event
|
||||
*
|
||||
* @package Google\Site_Kit
|
||||
* @copyright 2024 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\Advanced_Tracking;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Class for representing a single tracking event that Advanced_Tracking tracks.
|
||||
*
|
||||
* @since 1.18.0.
|
||||
* @since 1.121.0 Migrated from the Analytics (UA) namespace.
|
||||
* @access private
|
||||
* @ignore
|
||||
*/
|
||||
final class Event implements \JsonSerializable {
|
||||
|
||||
/**
|
||||
* The measurement event's configuration.
|
||||
*
|
||||
* @since 1.18.0.
|
||||
* @var array
|
||||
*/
|
||||
private $config;
|
||||
|
||||
/**
|
||||
* Event constructor.
|
||||
*
|
||||
* @since 1.18.0.
|
||||
*
|
||||
* @param array $config {
|
||||
* The event's configuration.
|
||||
*
|
||||
* @type string $action Required. The event action / event name to send.
|
||||
* @type string $on Required. The DOM event to send the event for.
|
||||
* @type string $selector Required, unless $on is 'DOMContentLoaded'. The DOM selector on which to listen
|
||||
* to the $on event.
|
||||
* @type array|null $metadata Optional. Associative array of event metadata to send, such as 'event_category',
|
||||
* 'event_label' etc, or null to not send any extra event data.
|
||||
* }
|
||||
* @throws Exception Thrown when config param is undefined.
|
||||
*/
|
||||
public function __construct( $config ) {
|
||||
$this->config = $this->validate_config( $config );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an associative event containing the event attributes.
|
||||
*
|
||||
* @since 1.18.0.
|
||||
*
|
||||
* @return array The configuration in JSON-serializable format.
|
||||
*/
|
||||
public function jsonSerialize() {
|
||||
return $this->config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the measurement event configuration.
|
||||
*
|
||||
* @since 1.18.0.
|
||||
*
|
||||
* @return array The config.
|
||||
*/
|
||||
public function get_config() {
|
||||
return $this->config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the configuration keys and value types.
|
||||
*
|
||||
* @since 1.18.0.
|
||||
*
|
||||
* @param array $config The event's configuration.
|
||||
* @return array The event's configuration.
|
||||
* @throws Exception Thrown when invalid keys or value type.
|
||||
*/
|
||||
private function validate_config( $config ) {
|
||||
$valid_keys = array(
|
||||
'action',
|
||||
'selector',
|
||||
'on',
|
||||
'metadata',
|
||||
);
|
||||
foreach ( $config as $key => $value ) {
|
||||
if ( ! in_array( $key, $valid_keys, true ) ) {
|
||||
throw new Exception( 'Invalid configuration parameter: ' . $key );
|
||||
}
|
||||
}
|
||||
if ( ! array_key_exists( 'metadata', $config ) ) {
|
||||
$config['metadata'] = null;
|
||||
}
|
||||
if ( array_key_exists( 'on', $config ) && 'DOMContentLoaded' === $config['on'] ) {
|
||||
$config['selector'] = '';
|
||||
}
|
||||
foreach ( $valid_keys as $key ) {
|
||||
if ( ! array_key_exists( $key, $config ) ) {
|
||||
throw new Exception( 'Missed configuration parameter: ' . $key );
|
||||
}
|
||||
}
|
||||
return $config;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
/**
|
||||
* Class Google\Site_Kit\Modules\Analytics_4\Advanced_Tracking\Event_List
|
||||
*
|
||||
* @package Google\Site_Kit
|
||||
* @copyright 2024 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\Advanced_Tracking;
|
||||
|
||||
/**
|
||||
* Base class representing a tracking event list.
|
||||
*
|
||||
* @since 1.18.0.
|
||||
* @since 1.121.0 Migrated from the Analytics (UA) namespace.
|
||||
* @access private
|
||||
* @ignore
|
||||
*/
|
||||
abstract class Event_List {
|
||||
|
||||
/**
|
||||
* Container for events.
|
||||
*
|
||||
* @since 1.18.0.
|
||||
* @var array Map of events for this list, keyed by their unique ID.
|
||||
*/
|
||||
private $events = array();
|
||||
|
||||
/**
|
||||
* Adds events or registers WordPress hook callbacks to add events.
|
||||
*
|
||||
* Children classes should extend this to add their events, either generically or by dynamically collecting
|
||||
* metadata through WordPress hooks.
|
||||
*
|
||||
* @since 1.18.0.
|
||||
*/
|
||||
abstract public function register();
|
||||
|
||||
/**
|
||||
* Adds a measurement event to the measurement events array.
|
||||
*
|
||||
* @since 1.18.0.
|
||||
*
|
||||
* @param Event $event The measurement event object.
|
||||
*/
|
||||
protected function add_event( Event $event ) {
|
||||
$hash = md5( wp_json_encode( $event ) );
|
||||
$this->events[ $hash ] = $event;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the measurement events array.
|
||||
*
|
||||
* @since 1.18.0.
|
||||
*
|
||||
* @return array The map of events for this list, keyed by their unique ID.
|
||||
*/
|
||||
public function get_events() {
|
||||
return $this->events;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
/**
|
||||
* Class Google\Site_Kit\Modules\Analytics_4\Advanced_Tracking\Event_List_Registry
|
||||
*
|
||||
* @package Google\Site_Kit\Modules\Analytics_4
|
||||
* @copyright 2024 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\Advanced_Tracking;
|
||||
|
||||
/**
|
||||
* Class for registering third party event lists.
|
||||
*
|
||||
* @since 1.18.0.
|
||||
* @since 1.121.0 Migrated from the Analytics (UA) namespace.
|
||||
* @access private
|
||||
* @ignore
|
||||
*/
|
||||
class Event_List_Registry {
|
||||
|
||||
/**
|
||||
* The list of registered event lists.
|
||||
*
|
||||
* @since 1.18.0.
|
||||
* @var Event_List[]
|
||||
*/
|
||||
private $event_lists = array();
|
||||
|
||||
/**
|
||||
* Registers an event list.
|
||||
*
|
||||
* @since 1.18.0.
|
||||
*
|
||||
* @param Event_List $event_list The event list to be registered.
|
||||
*/
|
||||
public function register_list( Event_List $event_list ) {
|
||||
$this->event_lists[] = $event_list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of registered event lists.
|
||||
*
|
||||
* @since 1.18.0.
|
||||
*
|
||||
* @return Event_List[] The list of registered event lists.
|
||||
*/
|
||||
public function get_lists() {
|
||||
return $this->event_lists;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
/**
|
||||
* Class Google\Site_Kit\Modules\Analytics_4\Advanced_Tracking\Script_Injector
|
||||
*
|
||||
* @package Google\Site_Kit\Modules\Analytics_4
|
||||
* @copyright 2024 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\Advanced_Tracking;
|
||||
|
||||
use Google\Site_Kit\Context;
|
||||
use Google\Site_Kit\Core\Assets\Manifest;
|
||||
use Google\Site_Kit\Core\Util\BC_Functions;
|
||||
|
||||
/**
|
||||
* Class for injecting JavaScript based on the registered event configurations.
|
||||
*
|
||||
* @since 1.18.0.
|
||||
* @since 1.121.0 Migrated from the Analytics (UA) namespace.
|
||||
* @access private
|
||||
* @ignore
|
||||
*/
|
||||
final class Script_Injector {
|
||||
|
||||
/**
|
||||
* Plugin context.
|
||||
*
|
||||
* @since 1.18.0.
|
||||
* @var Context
|
||||
*/
|
||||
protected $context;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @since 1.18.0.
|
||||
*
|
||||
* @param Context $context Plugin context.
|
||||
*/
|
||||
public function __construct( Context $context ) {
|
||||
$this->context = $context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates list of measurement event configurations and javascript to inject.
|
||||
*
|
||||
* @since 1.18.0.
|
||||
*
|
||||
* @param array $events The map of Event objects, keyed by their unique ID.
|
||||
*/
|
||||
public function inject_event_script( $events ) {
|
||||
if ( empty( $events ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
list( $filename ) = Manifest::get( 'analytics-advanced-tracking' );
|
||||
if ( ! $filename ) {
|
||||
// Get file contents of script and add it to the page, injecting event configurations into it.
|
||||
$filename = 'analytics-advanced-tracking.js';
|
||||
|
||||
}
|
||||
|
||||
$script_path = $this->context->path( "dist/assets/js/{$filename}" );
|
||||
|
||||
// phpcs:ignore WordPress.WP.AlternativeFunctions, WordPressVIPMinimum.Performance.FetchingRemoteData
|
||||
$script_content = file_get_contents( $script_path );
|
||||
if ( ! $script_content ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$data_var = sprintf(
|
||||
'var _googlesitekitAnalyticsTrackingData = %s;',
|
||||
wp_json_encode( array_values( $events ) )
|
||||
);
|
||||
BC_Functions::wp_print_inline_script_tag( $data_var . "\n" . $script_content );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
/**
|
||||
* Class Google\Site_Kit\Modules\Analytics_4\Audience_Settings
|
||||
*
|
||||
* @package Google\Site_Kit\Modules\Analytics_4
|
||||
* @copyright 2024 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;
|
||||
|
||||
use Google\Site_Kit\Core\Storage\User_Setting;
|
||||
use Google\Site_Kit\Core\Util\Sanitize;
|
||||
|
||||
/**
|
||||
* Class for Analytics 4 audience settings.
|
||||
*
|
||||
* @since 1.124.0
|
||||
* @access private
|
||||
* @ignore
|
||||
*/
|
||||
class Audience_Settings extends User_Setting {
|
||||
|
||||
/**
|
||||
* The user option name for audience setting.
|
||||
*/
|
||||
const OPTION = 'googlesitekit_audience_settings';
|
||||
|
||||
/**
|
||||
* Gets the expected value type.
|
||||
*
|
||||
* @since 1.124.0
|
||||
*
|
||||
* @return string The type name.
|
||||
*/
|
||||
protected function get_type() {
|
||||
return 'object';
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the default value.
|
||||
*
|
||||
* @since 1.124.0
|
||||
*
|
||||
* @return array The default value.
|
||||
*/
|
||||
protected function get_default() {
|
||||
return array(
|
||||
'configuredAudiences' => null,
|
||||
'isAudienceSegmentationWidgetHidden' => false,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges an array of settings to update.
|
||||
*
|
||||
* @since 1.124.0
|
||||
*
|
||||
* @param array $partial Partial settings array to save.
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function merge( array $partial ) {
|
||||
$settings = $this->get();
|
||||
$partial = array_filter(
|
||||
$partial,
|
||||
function ( $value ) {
|
||||
return null !== $value;
|
||||
}
|
||||
);
|
||||
|
||||
$allowed_settings = array(
|
||||
'configuredAudiences' => true,
|
||||
'isAudienceSegmentationWidgetHidden' => true,
|
||||
);
|
||||
|
||||
$updated = array_intersect_key( $partial, $allowed_settings );
|
||||
|
||||
return $this->set( array_merge( $settings, $updated ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the callback for sanitizing the setting's value before saving.
|
||||
*
|
||||
* @since 1.124.0
|
||||
*
|
||||
* @return callable Sanitize callback.
|
||||
*/
|
||||
protected function get_sanitize_callback() {
|
||||
return function ( $settings ) {
|
||||
if ( ! is_array( $settings ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$sanitized_settings = array();
|
||||
|
||||
if ( isset( $settings['configuredAudiences'] ) ) {
|
||||
$sanitized_settings['configuredAudiences'] = Sanitize::sanitize_string_list( $settings['configuredAudiences'] );
|
||||
}
|
||||
|
||||
if ( isset( $settings['isAudienceSegmentationWidgetHidden'] ) ) {
|
||||
$sanitized_settings['isAudienceSegmentationWidgetHidden'] = false !== $settings['isAudienceSegmentationWidgetHidden'];
|
||||
}
|
||||
|
||||
return $sanitized_settings;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
/**
|
||||
* Class Google\Site_Kit\Modules\Analytics_4\Custom_Dimensions_Data_Available
|
||||
*
|
||||
* @package Google\Site_Kit\Modules\Analytics_4
|
||||
* @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;
|
||||
|
||||
use Google\Site_Kit\Core\Storage\Transients;
|
||||
|
||||
/**
|
||||
* Class for updating Analytics 4 custom dimension data availability state.
|
||||
*
|
||||
* @since 1.113.0
|
||||
* @access private
|
||||
* @ignore
|
||||
*/
|
||||
class Custom_Dimensions_Data_Available {
|
||||
|
||||
/**
|
||||
* List of valid custom dimension slugs.
|
||||
*
|
||||
* @since 1.113.0
|
||||
* @var array
|
||||
*/
|
||||
const CUSTOM_DIMENSION_SLUGS = array(
|
||||
'googlesitekit_post_date',
|
||||
'googlesitekit_post_author',
|
||||
'googlesitekit_post_categories',
|
||||
'googlesitekit_post_type',
|
||||
);
|
||||
|
||||
/**
|
||||
* Transients instance.
|
||||
*
|
||||
* @since 1.113.0
|
||||
* @var Transients
|
||||
*/
|
||||
protected $transients;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @since 1.113.0
|
||||
*
|
||||
* @param Transients $transients Transients instance.
|
||||
*/
|
||||
public function __construct( Transients $transients ) {
|
||||
$this->transients = $transients;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data available transient name for the custom dimension.
|
||||
*
|
||||
* @since 1.113.0
|
||||
*
|
||||
* @param string $custom_dimension Custom dimension slug.
|
||||
* @return string Data available transient name.
|
||||
*/
|
||||
protected function get_data_available_transient_name( $custom_dimension ) {
|
||||
return "googlesitekit_custom_dimension_{$custom_dimension}_data_available";
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data availability for all custom dimensions.
|
||||
*
|
||||
* @since 1.113.0
|
||||
*
|
||||
* @return array Associative array of custom dimension names and their data availability state.
|
||||
*/
|
||||
public function get_data_availability() {
|
||||
return array_reduce(
|
||||
self::CUSTOM_DIMENSION_SLUGS,
|
||||
function ( $data_availability, $custom_dimension ) {
|
||||
$data_availability[ $custom_dimension ] = $this->is_data_available( $custom_dimension );
|
||||
return $data_availability;
|
||||
},
|
||||
array()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the data is available for the custom dimension.
|
||||
*
|
||||
* @since 1.113.0
|
||||
*
|
||||
* @param string $custom_dimension Custom dimension slug.
|
||||
* @return bool True if data is available, false otherwise.
|
||||
*/
|
||||
protected function is_data_available( $custom_dimension ) {
|
||||
return (bool) $this->transients->get( $this->get_data_available_transient_name( $custom_dimension ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the data available state for the custom dimension.
|
||||
*
|
||||
* @since 1.113.0
|
||||
*
|
||||
* @param string $custom_dimension Custom dimension slug.
|
||||
* @return bool True on success, false otherwise.
|
||||
*/
|
||||
public function set_data_available( $custom_dimension ) {
|
||||
return $this->transients->set( $this->get_data_available_transient_name( $custom_dimension ), true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the data available state for all custom dimensions.
|
||||
*
|
||||
* @since 1.113.0
|
||||
* @since 1.114.0 Added optional $custom_dimensions parameter.
|
||||
*
|
||||
* @param array $custom_dimensions Optional. List of custom dimension slugs to reset.
|
||||
*/
|
||||
public function reset_data_available(
|
||||
$custom_dimensions = self::CUSTOM_DIMENSION_SLUGS
|
||||
) {
|
||||
foreach ( $custom_dimensions as $custom_dimension ) {
|
||||
$this->transients->delete( $this->get_data_available_transient_name( $custom_dimension ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the custom dimension is valid.
|
||||
*
|
||||
* @since 1.113.0
|
||||
*
|
||||
* @param string $custom_dimension Custom dimension slug.
|
||||
* @return bool True if valid, false otherwise.
|
||||
*/
|
||||
public function is_valid_custom_dimension( $custom_dimension ) {
|
||||
return in_array( $custom_dimension, self::CUSTOM_DIMENSION_SLUGS, true );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
/**
|
||||
* Class AccountProvisioningService
|
||||
*
|
||||
* @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;
|
||||
|
||||
use Google\Site_Kit_Dependencies\Google\Service\GoogleAnalyticsAdmin;
|
||||
use Google\Site_Kit_Dependencies\Google_Client;
|
||||
|
||||
/**
|
||||
* Class for Analytics account provisioning service of the GoogleAnalytics Admin API.
|
||||
*
|
||||
* @since 1.98.0
|
||||
* @access private
|
||||
* @ignore
|
||||
*/
|
||||
class AccountProvisioningService extends GoogleAnalyticsAdmin {
|
||||
|
||||
/**
|
||||
* Accounts resource instance.
|
||||
*
|
||||
* @var AccountsResource
|
||||
*/
|
||||
public $accounts;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @since 1.98.0
|
||||
*
|
||||
* @param Google_Client $client The client used to deliver requests.
|
||||
* @param string $rootUrl The root URL used for requests to the service.
|
||||
*/
|
||||
public function __construct( Google_Client $client, $rootUrl = null ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName
|
||||
parent::__construct( $client, $rootUrl ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName
|
||||
|
||||
$this->accounts = new AccountsResource(
|
||||
$this,
|
||||
$this->serviceName, // phpcs:ignore WordPress.NamingConventions.ValidVariableName
|
||||
'accounts',
|
||||
array(
|
||||
'methods' => array(
|
||||
'provisionAccountTicket' => array(
|
||||
'path' => 'v1beta/accounts:provisionAccountTicket',
|
||||
'httpMethod' => 'POST',
|
||||
'parameters' => array(),
|
||||
),
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
/**
|
||||
* Class AccountsResource
|
||||
*
|
||||
* @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;
|
||||
|
||||
use Google\Site_Kit_Dependencies\Google\Service\GoogleAnalyticsAdmin\GoogleAnalyticsAdminV1betaProvisionAccountTicketResponse;
|
||||
use Google\Site_Kit_Dependencies\Google\Service\Resource;
|
||||
|
||||
/**
|
||||
* Class for representing the Accounts resource of the GoogleAnalytics Admin API for provisioning.
|
||||
*
|
||||
* @since 1.98.0
|
||||
* @access private
|
||||
* @ignore
|
||||
*/
|
||||
class AccountsResource extends Resource {
|
||||
|
||||
/**
|
||||
* Requests a ticket for creating an account.
|
||||
*
|
||||
* @since 1.98.0
|
||||
*
|
||||
* @param Proxy_GoogleAnalyticsAdminProvisionAccountTicketRequest $post_body The post body to send.
|
||||
* @param array $opt_params Optional parameters.
|
||||
* @return GoogleAnalyticsAdminV1betaProvisionAccountTicketResponse
|
||||
*/
|
||||
public function provisionAccountTicket( Proxy_GoogleAnalyticsAdminProvisionAccountTicketRequest $post_body, $opt_params = array() ) {
|
||||
$params = array( 'postBody' => $post_body );
|
||||
$params = array_merge( $params, $opt_params );
|
||||
|
||||
return $this->call(
|
||||
'provisionAccountTicket',
|
||||
array( $params ),
|
||||
GoogleAnalyticsAdminV1betaProvisionAccountTicketResponse::class
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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,0 +1,108 @@
|
||||
<?php
|
||||
/**
|
||||
* Class PropertiesAdSenseLinksService
|
||||
*
|
||||
* @package Google\Site_Kit\Modules\Analytics_4\GoogleAnalyticsAdmin
|
||||
* @copyright 2024 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;
|
||||
|
||||
use Google\Site_Kit_Dependencies\Google\Service\GoogleAnalyticsAdmin;
|
||||
use Google\Site_Kit_Dependencies\Google_Client;
|
||||
use Google\Site_Kit_Dependencies\Google_Service_GoogleAnalyticsAdmin_PropertiesAdSenseLinks_Resource as PropertiesAdSenseLinksResource;
|
||||
|
||||
/**
|
||||
* Class for managing GA4 AdSense Links.
|
||||
*
|
||||
* @since 1.119.0
|
||||
* @access private
|
||||
* @ignore
|
||||
*/
|
||||
class PropertiesAdSenseLinksService extends GoogleAnalyticsAdmin {
|
||||
|
||||
/**
|
||||
* PropertiesAdSenseLinksResource instance.
|
||||
*
|
||||
* @var PropertiesAdSenseLinksResource
|
||||
*/
|
||||
public $properties_adSenseLinks; // phpcs:ignore WordPress.NamingConventions.ValidVariableName
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @since 1.119.0
|
||||
*
|
||||
* @param Google_Client $client The client used to deliver requests.
|
||||
* @param string $rootUrl The root URL used for requests to the service.
|
||||
*/
|
||||
public function __construct( Google_Client $client, $rootUrl = null ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName
|
||||
parent::__construct( $client, $rootUrl ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName
|
||||
$this->version = 'v1alpha';
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidVariableName
|
||||
$this->properties_adSenseLinks = new PropertiesAdSenseLinksResource(
|
||||
$this,
|
||||
$this->serviceName, // phpcs:ignore WordPress.NamingConventions.ValidVariableName
|
||||
'adSenseLinks',
|
||||
array(
|
||||
'methods' => array(
|
||||
'create' => array(
|
||||
'path' => 'v1alpha/{+parent}/adSenseLinks',
|
||||
'httpMethod' => 'POST',
|
||||
'parameters' => array(
|
||||
'parent' => array(
|
||||
'location' => 'path',
|
||||
'type' => 'string',
|
||||
'required' => true,
|
||||
),
|
||||
),
|
||||
),
|
||||
'delete' => array(
|
||||
'path' => 'v1alpha/{+name}',
|
||||
'httpMethod' => 'DELETE',
|
||||
'parameters' => array(
|
||||
'name' => array(
|
||||
'location' => 'path',
|
||||
'type' => 'string',
|
||||
'required' => true,
|
||||
),
|
||||
),
|
||||
),
|
||||
'get' => array(
|
||||
'path' => 'v1alpha/{+name}',
|
||||
'httpMethod' => 'GET',
|
||||
'parameters' => array(
|
||||
'name' => array(
|
||||
'location' => 'path',
|
||||
'type' => 'string',
|
||||
'required' => true,
|
||||
),
|
||||
),
|
||||
),
|
||||
'list' => array(
|
||||
'path' => 'v1alpha/{+parent}/adSenseLinks',
|
||||
'httpMethod' => 'GET',
|
||||
'parameters' => array(
|
||||
'parent' => array(
|
||||
'location' => 'path',
|
||||
'type' => 'string',
|
||||
'required' => true,
|
||||
),
|
||||
'pageSize' => array(
|
||||
'location' => 'query',
|
||||
'type' => 'integer',
|
||||
),
|
||||
'pageToken' => array(
|
||||
'location' => 'query',
|
||||
'type' => 'string',
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
/**
|
||||
* Class PropertiesAudiencesService
|
||||
*
|
||||
* @package Google\Site_Kit\Modules\Analytics_4\GoogleAnalyticsAdmin
|
||||
* @copyright 2024 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;
|
||||
|
||||
use Google\Site_Kit_Dependencies\Google\Service\GoogleAnalyticsAdmin;
|
||||
use Google\Site_Kit_Dependencies\Google\Service\GoogleAnalyticsAdmin\Resource\PropertiesAudiences as PropertiesAudiences;
|
||||
use Google\Site_Kit_Dependencies\Google_Client;
|
||||
|
||||
/**
|
||||
* Class for managing GA4 audiences.
|
||||
*
|
||||
* @since 1.120.0
|
||||
* @access private
|
||||
* @ignore
|
||||
*/
|
||||
class PropertiesAudiencesService extends GoogleAnalyticsAdmin {
|
||||
|
||||
/**
|
||||
* PropertiesAudiences instance.
|
||||
*
|
||||
* @var PropertiesAudiences
|
||||
*/
|
||||
public $properties_audiences;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @since 1.120.0
|
||||
*
|
||||
* @param Google_Client $client The client used to deliver requests.
|
||||
* @param string $rootUrl The root URL used for requests to the service.
|
||||
*/
|
||||
public function __construct( Google_Client $client, $rootUrl = null ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName
|
||||
parent::__construct( $client, $rootUrl ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName
|
||||
$this->version = 'v1alpha';
|
||||
|
||||
$this->properties_audiences = new PropertiesAudiences(
|
||||
$this,
|
||||
$this->serviceName, // phpcs:ignore WordPress.NamingConventions.ValidVariableName
|
||||
'audiences',
|
||||
array(
|
||||
'methods' => array(
|
||||
'create' => array(
|
||||
'path' => 'v1alpha/{+parent}/audiences',
|
||||
'httpMethod' => 'POST',
|
||||
'parameters' => array(
|
||||
'parent' => array(
|
||||
'location' => 'path',
|
||||
'type' => 'string',
|
||||
'required' => true,
|
||||
),
|
||||
),
|
||||
),
|
||||
'list' => array(
|
||||
'path' => 'v1alpha/{+parent}/audiences',
|
||||
'httpMethod' => 'GET',
|
||||
'parameters' => array(
|
||||
'parent' => array(
|
||||
'location' => 'path',
|
||||
'type' => 'string',
|
||||
'required' => true,
|
||||
),
|
||||
'pageSize' => array(
|
||||
'location' => 'query',
|
||||
'type' => 'integer',
|
||||
),
|
||||
'pageToken' => array(
|
||||
'location' => 'query',
|
||||
'type' => 'string',
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
/**
|
||||
* Class PropertiesEnhancedMeasurementResource
|
||||
*
|
||||
* @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;
|
||||
|
||||
use Google\Site_Kit\Modules\Analytics_4\GoogleAnalyticsAdmin\EnhancedMeasurementSettingsModel;
|
||||
use Google\Site_Kit_Dependencies\Google\Service\Resource;
|
||||
|
||||
/**
|
||||
* The "enhancedMeasurementSettings" collection of methods.
|
||||
*/
|
||||
class PropertiesEnhancedMeasurementResource extends Resource {
|
||||
|
||||
/**
|
||||
* Returns the singleton enhanced measurement settings for this web stream. Note
|
||||
* that the stream must enable enhanced measurement for these settings to take
|
||||
* effect. (webDataStreams.getEnhancedMeasurementSettings)
|
||||
*
|
||||
* @since 1.110.0
|
||||
*
|
||||
* @param string $name Required. The name of the settings to lookup. Format: properties/{property_id}/webDataStreams/{stream_id}/enhancedMeasurementSettings
|
||||
* Example: "properties/1000/webDataStreams/2000/enhancedMeasurementSettings".
|
||||
* @param array $opt_params Optional parameters.
|
||||
* @return EnhancedMeasurementSettingsModel
|
||||
*/
|
||||
public function getEnhancedMeasurementSettings( $name, $opt_params = array() ) {
|
||||
$params = array( 'name' => $name );
|
||||
$params = array_merge( $params, $opt_params );
|
||||
return $this->call( 'getEnhancedMeasurementSettings', array( $params ), EnhancedMeasurementSettingsModel::class );
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the singleton enhanced measurement settings for this web stream. Note
|
||||
* that the stream must enable enhanced measurement for these settings to take
|
||||
* effect. (webDataStreams.updateEnhancedMeasurementSettings)
|
||||
*
|
||||
* @param string $name Output only. Resource name of this Data Stream. Format: properties/{property_id}/webDataStreams/{stream_id}/enhancedMeasurementSettings
|
||||
* Example: "properties/1000/webDataStreams/2000/enhancedMeasurementSettings".
|
||||
* @param EnhancedMeasurementSettingsModel $post_body The body of the request.
|
||||
* @param array $opt_params Optional parameters.
|
||||
*
|
||||
* @opt_param string updateMask Required. The list of fields to be updated.
|
||||
* Field names must be in snake case (e.g., "field_to_update"). Omitted fields
|
||||
* will not be updated. To replace the entire entity, use one path with the
|
||||
* string "*" to match all fields.
|
||||
* @return EnhancedMeasurementSettingsModel
|
||||
*/
|
||||
public function updateEnhancedMeasurementSettings( $name, EnhancedMeasurementSettingsModel $post_body, $opt_params = array() ) {
|
||||
$params = array(
|
||||
'name' => $name,
|
||||
'postBody' => $post_body,
|
||||
);
|
||||
$params = array_merge( $params, $opt_params );
|
||||
return $this->call( 'updateEnhancedMeasurementSettings', array( $params ), EnhancedMeasurementSettingsModel::class );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
/**
|
||||
* Class PropertiesEnhancedMeasurementService
|
||||
*
|
||||
* @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;
|
||||
|
||||
use Google\Site_Kit_Dependencies\Google\Service\GoogleAnalyticsAdmin;
|
||||
use Google\Site_Kit_Dependencies\Google_Client;
|
||||
|
||||
/**
|
||||
* Class for managing GA4 datastream enhanced measurement settings.
|
||||
*
|
||||
* @since 1.110.0
|
||||
* @access private
|
||||
* @ignore
|
||||
*/
|
||||
class PropertiesEnhancedMeasurementService extends GoogleAnalyticsAdmin {
|
||||
|
||||
/**
|
||||
* PropertiesEnhancedMeasurementResource instance.
|
||||
*
|
||||
* @var PropertiesEnhancedMeasurementResource
|
||||
*/
|
||||
public $properties_enhancedMeasurements; // phpcs:ignore WordPress.NamingConventions.ValidVariableName
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @since 1.110.0
|
||||
*
|
||||
* @param Google_Client $client The client used to deliver requests.
|
||||
* @param string $rootUrl The root URL used for requests to the service.
|
||||
*/
|
||||
public function __construct( Google_Client $client, $rootUrl = null ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName
|
||||
parent::__construct( $client, $rootUrl ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName
|
||||
$this->version = 'v1alpha';
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidVariableName
|
||||
$this->properties_enhancedMeasurements = new PropertiesEnhancedMeasurementResource(
|
||||
$this,
|
||||
$this->serviceName, // phpcs:ignore WordPress.NamingConventions.ValidVariableName
|
||||
'enhancedMeasurements',
|
||||
array(
|
||||
'methods' => array(
|
||||
'getEnhancedMeasurementSettings' => array(
|
||||
'path' => 'v1alpha/{+name}',
|
||||
'httpMethod' => 'GET',
|
||||
'parameters' => array(
|
||||
'name' => array(
|
||||
'location' => 'path',
|
||||
'type' => 'string',
|
||||
'required' => true,
|
||||
),
|
||||
),
|
||||
),
|
||||
'updateEnhancedMeasurementSettings' => array(
|
||||
'path' => 'v1alpha/{+name}',
|
||||
'httpMethod' => 'PATCH',
|
||||
'parameters' => array(
|
||||
'name' => array(
|
||||
'location' => 'path',
|
||||
'type' => 'string',
|
||||
'required' => true,
|
||||
),
|
||||
'updateMask' => array(
|
||||
'location' => 'query',
|
||||
'type' => 'string',
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
/**
|
||||
* Class Proxy_GoogleAnalyticsAdminProvisionAccountTicketRequest
|
||||
*
|
||||
* @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;
|
||||
|
||||
use Google\Site_Kit_Dependencies\Google\Service\GoogleAnalyticsAdmin\GoogleAnalyticsAdminV1betaProvisionAccountTicketRequest;
|
||||
|
||||
/**
|
||||
* Class for representing a proxied account ticket provisioning request body.
|
||||
*
|
||||
* @since 1.98.0
|
||||
* @access private
|
||||
* @ignore
|
||||
*/
|
||||
class Proxy_GoogleAnalyticsAdminProvisionAccountTicketRequest extends GoogleAnalyticsAdminV1betaProvisionAccountTicketRequest {
|
||||
/**
|
||||
* The site ID.
|
||||
*
|
||||
* @since 1.98.0
|
||||
* @var string
|
||||
*/
|
||||
public $site_id = '';
|
||||
|
||||
/**
|
||||
* The site secret.
|
||||
*
|
||||
* @since 1.98.0
|
||||
* @var string
|
||||
*/
|
||||
public $site_secret = '';
|
||||
|
||||
/**
|
||||
* Gets the site ID.
|
||||
*
|
||||
* @since 1.98.0
|
||||
*/
|
||||
public function getSiteId() {
|
||||
return $this->site_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the site ID.
|
||||
*
|
||||
* @since 1.98.0
|
||||
*
|
||||
* @param string $id The site id.
|
||||
*/
|
||||
public function setSiteId( $id ) {
|
||||
$this->site_id = $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the site secret.
|
||||
*
|
||||
* @since 1.98.0
|
||||
*/
|
||||
public function getSiteSecret() {
|
||||
return $this->site_secret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the site secret.
|
||||
*
|
||||
* @since 1.98.0
|
||||
*
|
||||
* @param string $secret The site secret.
|
||||
*/
|
||||
public function setSiteSecret( $secret ) {
|
||||
$this->site_secret = $secret;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
<?php
|
||||
/**
|
||||
* Class Google\Site_Kit\Modules\Analytics_4\Report
|
||||
*
|
||||
* @package Google\Site_Kit\Modules\Analytics_4
|
||||
* @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;
|
||||
|
||||
use Google\Site_Kit\Context;
|
||||
use Google\Site_Kit\Core\REST_API\Data_Request;
|
||||
use Google\Site_Kit\Core\Util\Date;
|
||||
use Google\Site_Kit_Dependencies\Google\Service\AnalyticsData\DateRange as Google_Service_AnalyticsData_DateRange;
|
||||
use Google\Site_Kit_Dependencies\Google\Service\AnalyticsData\Dimension as Google_Service_AnalyticsData_Dimension;
|
||||
use Google\Site_Kit_Dependencies\Google\Service\AnalyticsData\DimensionOrderBy as Google_Service_AnalyticsData_DimensionOrderBy;
|
||||
use Google\Site_Kit_Dependencies\Google\Service\AnalyticsData\MetricOrderBy as Google_Service_AnalyticsData_MetricOrderBy;
|
||||
use Google\Site_Kit_Dependencies\Google\Service\AnalyticsData\OrderBy as Google_Service_AnalyticsData_OrderBy;
|
||||
|
||||
/**
|
||||
* The base class for Analytics 4 reports.
|
||||
*
|
||||
* @since 1.99.0
|
||||
* @access private
|
||||
* @ignore
|
||||
*/
|
||||
class Report {
|
||||
|
||||
/**
|
||||
* Plugin context.
|
||||
*
|
||||
* @since 1.99.0
|
||||
* @var Context
|
||||
*/
|
||||
protected $context;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @since 1.99.0
|
||||
*
|
||||
* @param Context $context Plugin context.
|
||||
*/
|
||||
public function __construct( Context $context ) {
|
||||
$this->context = $context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses report dimensions received in the request params.
|
||||
*
|
||||
* @since 1.99.0
|
||||
*
|
||||
* @param Data_Request $data Data request object.
|
||||
* @return Google_Service_AnalyticsData_Dimension[] An array of AnalyticsData Dimension objects.
|
||||
*/
|
||||
protected function parse_dimensions( Data_Request $data ) {
|
||||
$dimensions = $data['dimensions'];
|
||||
if ( empty( $dimensions ) || ( ! is_string( $dimensions ) && ! is_array( $dimensions ) ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
if ( is_string( $dimensions ) ) {
|
||||
$dimensions = explode( ',', $dimensions );
|
||||
} elseif ( is_array( $dimensions ) && ! wp_is_numeric_array( $dimensions ) ) { // If single object is passed.
|
||||
$dimensions = array( $dimensions );
|
||||
}
|
||||
|
||||
$dimensions = array_filter(
|
||||
array_map(
|
||||
function ( $dimension_def ) {
|
||||
$dimension = new Google_Service_AnalyticsData_Dimension();
|
||||
|
||||
if ( is_string( $dimension_def ) ) {
|
||||
$dimension->setName( $dimension_def );
|
||||
} elseif ( is_array( $dimension_def ) && ! empty( $dimension_def['name'] ) ) {
|
||||
$dimension->setName( $dimension_def['name'] );
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $dimension;
|
||||
},
|
||||
array_filter( $dimensions )
|
||||
)
|
||||
);
|
||||
|
||||
return $dimensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses report date ranges received in the request params.
|
||||
*
|
||||
* @since 1.99.0
|
||||
*
|
||||
* @param Data_Request $data Data request object.
|
||||
* @return Google_Service_AnalyticsData_DateRange[] An array of AnalyticsData DateRange objects.
|
||||
*/
|
||||
protected function parse_dateranges( Data_Request $data ) {
|
||||
$date_ranges = array();
|
||||
$start_date = $data['startDate'];
|
||||
$end_date = $data['endDate'];
|
||||
if ( strtotime( $start_date ) && strtotime( $end_date ) ) {
|
||||
$compare_start_date = $data['compareStartDate'];
|
||||
$compare_end_date = $data['compareEndDate'];
|
||||
$date_ranges[] = array( $start_date, $end_date );
|
||||
|
||||
// When using multiple date ranges, it changes the structure of the response:
|
||||
// Aggregate properties (minimum, maximum, totals) will have an entry per date range.
|
||||
// The rows property will have additional row entries for each date range.
|
||||
if ( strtotime( $compare_start_date ) && strtotime( $compare_end_date ) ) {
|
||||
$date_ranges[] = array( $compare_start_date, $compare_end_date );
|
||||
}
|
||||
} else {
|
||||
// Default the date range to the last 28 days.
|
||||
$date_ranges[] = Date::parse_date_range( 'last-28-days', 1 );
|
||||
}
|
||||
|
||||
$date_ranges = array_map(
|
||||
function ( $date_range ) {
|
||||
list ( $start_date, $end_date ) = $date_range;
|
||||
$date_range = new Google_Service_AnalyticsData_DateRange();
|
||||
$date_range->setStartDate( $start_date );
|
||||
$date_range->setEndDate( $end_date );
|
||||
|
||||
return $date_range;
|
||||
},
|
||||
$date_ranges
|
||||
);
|
||||
|
||||
return $date_ranges;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the orderby value of the data request into an array of AnalyticsData OrderBy object instances.
|
||||
*
|
||||
* @since 1.99.0
|
||||
*
|
||||
* @param Data_Request $data Data request object.
|
||||
* @return Google_Service_AnalyticsData_OrderBy[] An array of AnalyticsData OrderBy objects.
|
||||
*/
|
||||
protected function parse_orderby( Data_Request $data ) {
|
||||
$orderby = $data['orderby'];
|
||||
if ( empty( $orderby ) || ! is_array( $orderby ) || ! wp_is_numeric_array( $orderby ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$results = array_map(
|
||||
function ( $order_def ) {
|
||||
$order_by = new Google_Service_AnalyticsData_OrderBy();
|
||||
$order_by->setDesc( ! empty( $order_def['desc'] ) );
|
||||
|
||||
if ( isset( $order_def['metric'] ) && isset( $order_def['metric']['metricName'] ) ) {
|
||||
$metric_order_by = new Google_Service_AnalyticsData_MetricOrderBy();
|
||||
$metric_order_by->setMetricName( $order_def['metric']['metricName'] );
|
||||
$order_by->setMetric( $metric_order_by );
|
||||
} elseif ( isset( $order_def['dimension'] ) && isset( $order_def['dimension']['dimensionName'] ) ) {
|
||||
$dimension_order_by = new Google_Service_AnalyticsData_DimensionOrderBy();
|
||||
$dimension_order_by->setDimensionName( $order_def['dimension']['dimensionName'] );
|
||||
$order_by->setDimension( $dimension_order_by );
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $order_by;
|
||||
},
|
||||
$orderby
|
||||
);
|
||||
|
||||
$results = array_filter( $results );
|
||||
$results = array_values( $results );
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
/**
|
||||
* Class Google\Site_Kit\Modules\Analytics_4\Report\Dimension_Filter\Filter
|
||||
*
|
||||
* @package Google\Site_Kit\Modules\Analytics_4\Report\Dimension_Filter
|
||||
* @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\Report\Dimension_Filter;
|
||||
|
||||
use Google\Site_Kit_Dependencies\Google\Service\AnalyticsData\FilterExpression as Google_Service_AnalyticsData_FilterExpression;
|
||||
|
||||
/**
|
||||
* Interface for a dimension filter class.
|
||||
*
|
||||
* @since 1.106.0
|
||||
*/
|
||||
interface Filter {
|
||||
|
||||
/**
|
||||
* Converts the dimension filter into the GA4 compatible dimension filter expression.
|
||||
*
|
||||
* @since 1.106.0
|
||||
*
|
||||
* @param string $dimension_name The dimension name.
|
||||
* @param mixed $dimension_value The dimension filter value.
|
||||
* @return Google_Service_AnalyticsData_FilterExpression The filter expression instance.
|
||||
*/
|
||||
public function parse_filter_expression( $dimension_name, $dimension_value );
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
/**
|
||||
* Class Google\Site_Kit\Modules\Analytics_4\Report\Dimension_Filter\In_List_Filter
|
||||
*
|
||||
* @package Google\Site_Kit\Modules\Analytics_4\Report\Dimension_Filter
|
||||
* @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\Report\Dimension_Filter;
|
||||
|
||||
use Google\Site_Kit_Dependencies\Google\Service\AnalyticsData\Filter as Google_Service_AnalyticsData_Filter;
|
||||
use Google\Site_Kit_Dependencies\Google\Service\AnalyticsData\FilterExpression as Google_Service_AnalyticsData_FilterExpression;
|
||||
use Google\Site_Kit_Dependencies\Google\Service\AnalyticsData\InListFilter as Google_Service_AnalyticsData_InListFilter;
|
||||
|
||||
/**
|
||||
* Class for parsing the dimension in-list filter.
|
||||
*
|
||||
* @since 1.106.0
|
||||
* @access private
|
||||
* @ignore
|
||||
*/
|
||||
class In_List_Filter implements Filter {
|
||||
|
||||
/**
|
||||
* Converts the dimension filter into the GA4 compatible dimension filter expression.
|
||||
*
|
||||
* @since 1.106.0
|
||||
*
|
||||
* @param string $dimension_name The dimension name.
|
||||
* @param mixed $dimension_value The dimension filter value.
|
||||
* @return Google_Service_AnalyticsData_FilterExpression The filter expression instance.
|
||||
*/
|
||||
public function parse_filter_expression( $dimension_name, $dimension_value ) {
|
||||
$in_list_filter = new Google_Service_AnalyticsData_InListFilter();
|
||||
$in_list_filter->setValues( $dimension_value );
|
||||
|
||||
$filter = new Google_Service_AnalyticsData_Filter();
|
||||
$filter->setFieldName( $dimension_name );
|
||||
$filter->setInListFilter( $in_list_filter );
|
||||
|
||||
$expression = new Google_Service_AnalyticsData_FilterExpression();
|
||||
$expression->setFilter( $filter );
|
||||
|
||||
return $expression;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
/**
|
||||
* Class Google\Site_Kit\Modules\Analytics_4\Report\Dimension_Filter\String_Filter
|
||||
*
|
||||
* @package Google\Site_Kit\Modules\Analytics_4\Report\Dimension_Filter
|
||||
* @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\Report\Dimension_Filter;
|
||||
|
||||
use Google\Site_Kit_Dependencies\Google\Service\AnalyticsData\Filter as Google_Service_AnalyticsData_Filter;
|
||||
use Google\Site_Kit_Dependencies\Google\Service\AnalyticsData\FilterExpression as Google_Service_AnalyticsData_FilterExpression;
|
||||
use Google\Site_Kit_Dependencies\Google\Service\AnalyticsData\FilterExpressionList as Google_Service_AnalyticsData_FilterExpressionList;
|
||||
use Google\Site_Kit_Dependencies\Google\Service\AnalyticsData\StringFilter as Google_Service_AnalyticsData_StringFilter;
|
||||
|
||||
/**
|
||||
* Class for parsing the dimension string filter.
|
||||
*
|
||||
* @since 1.106.0
|
||||
* @access private
|
||||
* @ignore
|
||||
*/
|
||||
class String_Filter implements Filter {
|
||||
|
||||
/**
|
||||
* Converts the dimension filter into the GA4 compatible dimension filter expression.
|
||||
*
|
||||
* @since 1.106.0
|
||||
*
|
||||
* @param string $dimension_name The dimension name.
|
||||
* @param mixed $dimension_value The dimension filter value.
|
||||
* @return Google_Service_AnalyticsData_FilterExpression The filter expression instance.
|
||||
*/
|
||||
public function parse_filter_expression( $dimension_name, $dimension_value ) {
|
||||
$match_type = isset( $dimension_value['matchType'] )
|
||||
? $dimension_value['matchType']
|
||||
: 'EXACT';
|
||||
|
||||
$filter_value = isset( $dimension_value['value'] )
|
||||
? $dimension_value['value']
|
||||
: $dimension_value;
|
||||
|
||||
// If there are many values for this filter, then it means that we want to find
|
||||
// rows where dimension are included in the list of provided values. In this case,
|
||||
// we need to create a nested filter expression that contains separate string filters
|
||||
// for each item in the list and combined into the "OR" group.
|
||||
if ( is_array( $filter_value ) ) {
|
||||
$expressions = array();
|
||||
foreach ( $filter_value as $value ) {
|
||||
$expressions[] = $this->compose_individual_filter_expression(
|
||||
$dimension_name,
|
||||
$match_type,
|
||||
$value
|
||||
);
|
||||
}
|
||||
|
||||
$expression_list = new Google_Service_AnalyticsData_FilterExpressionList();
|
||||
$expression_list->setExpressions( $expressions );
|
||||
|
||||
$filter_expression = new Google_Service_AnalyticsData_FilterExpression();
|
||||
$filter_expression->setOrGroup( $expression_list );
|
||||
|
||||
return $filter_expression;
|
||||
}
|
||||
|
||||
// If we have a single value for the filter, then we should use just a single
|
||||
// string filter expression and there is no need to create a nested one.
|
||||
return $this->compose_individual_filter_expression(
|
||||
$dimension_name,
|
||||
$match_type,
|
||||
$filter_value
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Composes individual filter expression and returns it.
|
||||
*
|
||||
* @since 1.106.0
|
||||
*
|
||||
* @param string $dimension_name The dimension name.
|
||||
* @param string $match_type The dimension filter match type.
|
||||
* @param mixed $value The dimension filter value.
|
||||
* @return Google_Service_AnalyticsData_FilterExpression The filter expression instance.
|
||||
*/
|
||||
protected function compose_individual_filter_expression( $dimension_name, $match_type, $value ) {
|
||||
$string_filter = new Google_Service_AnalyticsData_StringFilter();
|
||||
$string_filter->setMatchType( $match_type );
|
||||
$string_filter->setValue( $value );
|
||||
|
||||
$filter = new Google_Service_AnalyticsData_Filter();
|
||||
$filter->setFieldName( $dimension_name );
|
||||
$filter->setStringFilter( $string_filter );
|
||||
|
||||
$filter_expression = new Google_Service_AnalyticsData_FilterExpression();
|
||||
$filter_expression->setFilter( $filter );
|
||||
|
||||
return $filter_expression;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
/**
|
||||
* Class Google\Site_Kit\Modules\Analytics_4\Report\Metric_Filter\Between_Filter
|
||||
*
|
||||
* @package Google\Site_Kit\Modules\Analytics_4\Report\Metric_Filter
|
||||
* @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\Report\Filters;
|
||||
|
||||
use Google\Site_Kit_Dependencies\Google\Service\AnalyticsData\Filter as Google_Service_AnalyticsData_Filter;
|
||||
use Google\Site_Kit_Dependencies\Google\Service\AnalyticsData\FilterExpression as Google_Service_AnalyticsData_FilterExpression;
|
||||
use Google\Site_Kit_Dependencies\Google\Service\AnalyticsData\BetweenFilter as Google_Service_AnalyticsData_BetweenFilter;
|
||||
use Google\Site_Kit_Dependencies\Google\Service\AnalyticsData\NumericValue as NumericValue;
|
||||
|
||||
/**
|
||||
* Class for parsing the metric between filter.
|
||||
*
|
||||
* @since 1.111.0
|
||||
* @access private
|
||||
* @ignore
|
||||
*/
|
||||
class Between_Filter {
|
||||
|
||||
/**
|
||||
* Converts the metric filter into the GA4 compatible metric filter expression.
|
||||
*
|
||||
* @since 1.111.0
|
||||
*
|
||||
* @param string $metric_name The metric name.
|
||||
* @param integer $from_value The filter from value.
|
||||
* @param integer $to_value The filter to value.
|
||||
* @return Google_Service_AnalyticsData_FilterExpression The filter expression instance.
|
||||
*/
|
||||
public function parse_filter_expression( $metric_name, $from_value, $to_value ) {
|
||||
$numeric_from_value = new NumericValue();
|
||||
$numeric_from_value->setInt64Value( $from_value );
|
||||
|
||||
$numeric_to_value = new NumericValue();
|
||||
$numeric_to_value->setInt64Value( $to_value );
|
||||
|
||||
$between_filter = new Google_Service_AnalyticsData_BetweenFilter();
|
||||
$between_filter->setFromValue( $numeric_from_value );
|
||||
$between_filter->setToValue( $numeric_to_value );
|
||||
|
||||
$filter = new Google_Service_AnalyticsData_Filter();
|
||||
$filter->setFieldName( $metric_name );
|
||||
$filter->setBetweenFilter( $between_filter );
|
||||
|
||||
$expression = new Google_Service_AnalyticsData_FilterExpression();
|
||||
$expression->setFilter( $filter );
|
||||
|
||||
return $expression;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
/**
|
||||
* Class Google\Site_Kit\Modules\Analytics_4\Report\Metric_Filter\Numeric_Filter
|
||||
*
|
||||
* @package Google\Site_Kit\Modules\Analytics_4\Report\Metric_Filter
|
||||
* @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\Report\Filters;
|
||||
|
||||
use Google\Site_Kit_Dependencies\Google\Service\AnalyticsData\Filter as Google_Service_AnalyticsData_Filter;
|
||||
use Google\Site_Kit_Dependencies\Google\Service\AnalyticsData\FilterExpression as Google_Service_AnalyticsData_FilterExpression;
|
||||
use Google\Site_Kit_Dependencies\Google\Service\AnalyticsData\NumericFilter as Google_Service_AnalyticsData_NumericFilter;
|
||||
use Google\Site_Kit_Dependencies\Google\Service\AnalyticsData\NumericValue as NumericValue;
|
||||
|
||||
/**
|
||||
* Class for parsing the metric numeric filter.
|
||||
*
|
||||
* @since 1.111.0
|
||||
* @access private
|
||||
* @ignore
|
||||
*/
|
||||
class Numeric_Filter {
|
||||
|
||||
/**
|
||||
* Converts the metric filter into the GA4 compatible metric filter expression.
|
||||
*
|
||||
* @since 1.111.0
|
||||
*
|
||||
* @param string $metric_name The metric name.
|
||||
* @param string $operation The filter operation.
|
||||
* @param integer $value The filter value.
|
||||
* @return Google_Service_AnalyticsData_FilterExpression The filter expression instance.
|
||||
*/
|
||||
public function parse_filter_expression( $metric_name, $operation, $value ) {
|
||||
$numeric_value = new NumericValue();
|
||||
$numeric_value->setInt64Value( $value );
|
||||
|
||||
$numeric_filter = new Google_Service_AnalyticsData_NumericFilter();
|
||||
$numeric_filter->setOperation( $operation );
|
||||
$numeric_filter->setValue( $numeric_value );
|
||||
|
||||
$filter = new Google_Service_AnalyticsData_Filter();
|
||||
$filter->setFieldName( $metric_name );
|
||||
$filter->setNumericFilter( $numeric_filter );
|
||||
|
||||
$expression = new Google_Service_AnalyticsData_FilterExpression();
|
||||
$expression->setFilter( $filter );
|
||||
|
||||
return $expression;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,529 @@
|
||||
<?php
|
||||
/**
|
||||
* Class Google\Site_Kit\Modules\Analytics_4\Report\Request
|
||||
*
|
||||
* @package Google\Site_Kit\Modules\Analytics_4\Report
|
||||
* @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\Report;
|
||||
|
||||
use Google\Site_Kit\Core\REST_API\Data_Request;
|
||||
use Google\Site_Kit\Core\Validation\Exception\Invalid_Report_Dimensions_Exception;
|
||||
use Google\Site_Kit\Core\Validation\Exception\Invalid_Report_Metrics_Exception;
|
||||
use Google\Site_Kit\Core\Util\URL;
|
||||
use Google\Site_Kit\Modules\Analytics_4\Report;
|
||||
use Google\Site_Kit\Modules\Analytics_4\Report\Dimension_Filter\In_List_Filter;
|
||||
use Google\Site_Kit\Modules\Analytics_4\Report\Dimension_Filter\String_Filter;
|
||||
use Google\Site_Kit\Modules\Analytics_4\Report\Filters\Numeric_Filter;
|
||||
use Google\Site_Kit\Modules\Analytics_4\Report\Filters\Between_Filter;
|
||||
use Google\Site_Kit_Dependencies\Google\Service\AnalyticsData\DateRange as Google_Service_AnalyticsData_DateRange;
|
||||
use Google\Site_Kit_Dependencies\Google\Service\AnalyticsData\Dimension as Google_Service_AnalyticsData_Dimension;
|
||||
use Google\Site_Kit_Dependencies\Google\Service\AnalyticsData\FilterExpression as Google_Service_AnalyticsData_FilterExpression;
|
||||
use Google\Site_Kit_Dependencies\Google\Service\AnalyticsData\FilterExpressionList as Google_Service_AnalyticsData_FilterExpressionList;
|
||||
use Google\Site_Kit_Dependencies\Google\Service\AnalyticsData\RunReportRequest as Google_Service_AnalyticsData_RunReportRequest;
|
||||
use Google\Site_Kit_Dependencies\Google\Service\AnalyticsData\Metric as Google_Service_AnalyticsData_Metric;
|
||||
use WP_Error;
|
||||
|
||||
/**
|
||||
* Class for Analytics 4 report requests.
|
||||
*
|
||||
* @since 1.99.0
|
||||
* @access private
|
||||
* @ignore
|
||||
*/
|
||||
class Request extends Report {
|
||||
|
||||
/**
|
||||
* Creates and executes a new Analytics 4 report request.
|
||||
*
|
||||
* @since 1.99.0
|
||||
*
|
||||
* @param Data_Request $data Data request object.
|
||||
* @param bool $is_shared_request Determines whether the current request is shared or not.
|
||||
* @return RequestInterface|WP_Error Request object on success, or WP_Error on failure.
|
||||
*/
|
||||
public function create_request( Data_Request $data, $is_shared_request ) {
|
||||
$request = new Google_Service_AnalyticsData_RunReportRequest();
|
||||
$request->setKeepEmptyRows( true );
|
||||
$request->setMetricAggregations( array( 'TOTAL', 'MINIMUM', 'MAXIMUM' ) );
|
||||
|
||||
if ( ! empty( $data['limit'] ) ) {
|
||||
$request->setLimit( $data['limit'] );
|
||||
}
|
||||
|
||||
$dimensions = $this->parse_dimensions( $data );
|
||||
if ( ! empty( $dimensions ) ) {
|
||||
if ( $is_shared_request ) {
|
||||
try {
|
||||
$this->validate_shared_dimensions( $dimensions );
|
||||
} catch ( Invalid_Report_Dimensions_Exception $exception ) {
|
||||
return new WP_Error(
|
||||
'invalid_analytics_4_report_dimensions',
|
||||
$exception->getMessage()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$request->setDimensions( (array) $dimensions );
|
||||
}
|
||||
|
||||
$dimension_filters = $this->parse_dimension_filters( $data );
|
||||
$request->setDimensionFilter( $dimension_filters );
|
||||
|
||||
$metric_filters = $this->parse_metric_filters( $data );
|
||||
if ( ! empty( $metric_filters ) ) {
|
||||
$request->setMetricFilter( $metric_filters );
|
||||
}
|
||||
|
||||
$date_ranges = $this->parse_dateranges( $data );
|
||||
$request->setDateRanges( $date_ranges );
|
||||
|
||||
$metrics = $data['metrics'];
|
||||
if ( is_string( $metrics ) || is_array( $metrics ) ) {
|
||||
if ( is_string( $metrics ) ) {
|
||||
$metrics = explode( ',', $data['metrics'] );
|
||||
} elseif ( is_array( $metrics ) && ! wp_is_numeric_array( $metrics ) ) { // If single object is passed.
|
||||
$metrics = array( $metrics );
|
||||
}
|
||||
|
||||
$metrics = array_filter(
|
||||
array_map(
|
||||
function ( $metric_def ) {
|
||||
$metric = new Google_Service_AnalyticsData_Metric();
|
||||
|
||||
if ( is_string( $metric_def ) ) {
|
||||
$metric->setName( $metric_def );
|
||||
} elseif ( is_array( $metric_def ) ) {
|
||||
$metric->setName( $metric_def['name'] );
|
||||
if ( ! empty( $metric_def['expression'] ) ) {
|
||||
$metric->setExpression( $metric_def['expression'] );
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $metric;
|
||||
},
|
||||
$metrics
|
||||
)
|
||||
);
|
||||
|
||||
if ( ! empty( $metrics ) ) {
|
||||
try {
|
||||
$this->validate_metrics( $metrics );
|
||||
} catch ( Invalid_Report_Metrics_Exception $exception ) {
|
||||
return new WP_Error(
|
||||
'invalid_analytics_4_report_metrics',
|
||||
$exception->getMessage()
|
||||
);
|
||||
}
|
||||
|
||||
if ( $is_shared_request ) {
|
||||
try {
|
||||
$this->validate_shared_metrics( $metrics );
|
||||
} catch ( Invalid_Report_Metrics_Exception $exception ) {
|
||||
return new WP_Error(
|
||||
'invalid_analytics_4_report_metrics',
|
||||
$exception->getMessage()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$request->setMetrics( $metrics );
|
||||
}
|
||||
}
|
||||
|
||||
// Order by.
|
||||
$orderby = $this->parse_orderby( $data );
|
||||
if ( ! empty( $orderby ) ) {
|
||||
$request->setOrderBys( $orderby );
|
||||
}
|
||||
|
||||
return $request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the given metrics for a report.
|
||||
*
|
||||
* Metrics must have valid names, matching the regular expression ^[a-zA-Z0-9_]+$ in keeping with the GA4 API.
|
||||
*
|
||||
* @since 1.99.0
|
||||
*
|
||||
* @param Google_Service_AnalyticsData_Metric[] $metrics The metrics to validate.
|
||||
* @throws Invalid_Report_Metrics_Exception Thrown if the metrics are invalid.
|
||||
*/
|
||||
protected function validate_metrics( $metrics ) {
|
||||
$valid_name_expression = '^[a-zA-Z0-9_]+$';
|
||||
|
||||
$invalid_metrics = array_map(
|
||||
function ( $metric ) {
|
||||
return $metric->getName();
|
||||
},
|
||||
array_filter(
|
||||
$metrics,
|
||||
function ( $metric ) use ( $valid_name_expression ) {
|
||||
return ! preg_match( "#$valid_name_expression#", $metric->getName() );
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
if ( count( $invalid_metrics ) > 0 ) {
|
||||
$message = count( $invalid_metrics ) > 1 ? sprintf(
|
||||
/* translators: 1: the regular expression for a valid name, 2: a comma separated list of the invalid metrics. */
|
||||
__(
|
||||
'Metric names should match the expression %1$s: %2$s',
|
||||
'google-site-kit'
|
||||
),
|
||||
$valid_name_expression,
|
||||
join(
|
||||
/* translators: used between list items, there is a space after the comma. */
|
||||
__( ', ', 'google-site-kit' ),
|
||||
$invalid_metrics
|
||||
)
|
||||
) : sprintf(
|
||||
/* translators: 1: the regular expression for a valid name, 2: the invalid metric. */
|
||||
__(
|
||||
'Metric name should match the expression %1$s: %2$s',
|
||||
'google-site-kit'
|
||||
),
|
||||
$valid_name_expression,
|
||||
$invalid_metrics[0]
|
||||
);
|
||||
|
||||
throw new Invalid_Report_Metrics_Exception( $message );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the report metrics for a shared request.
|
||||
*
|
||||
* @since 1.99.0
|
||||
*
|
||||
* @param Google_Service_AnalyticsData_Metric[] $metrics The metrics to validate.
|
||||
* @throws Invalid_Report_Metrics_Exception Thrown if the metrics are invalid.
|
||||
*/
|
||||
protected function validate_shared_metrics( $metrics ) {
|
||||
$valid_metrics = apply_filters(
|
||||
'googlesitekit_shareable_analytics_4_metrics',
|
||||
array(
|
||||
'activeUsers',
|
||||
'averageSessionDuration',
|
||||
'bounceRate',
|
||||
'conversions',
|
||||
'engagedSessions',
|
||||
'engagementRate',
|
||||
'screenPageViews',
|
||||
'screenPageViewsPerSession',
|
||||
'sessions',
|
||||
'sessionConversionRate',
|
||||
'sessionsPerUser',
|
||||
'totalAdRevenue',
|
||||
'totalUsers',
|
||||
)
|
||||
);
|
||||
|
||||
$invalid_metrics = array_diff(
|
||||
array_map(
|
||||
function ( $metric ) {
|
||||
// If there is an expression, it means the name is there as an alias, otherwise the name should be a valid metric name.
|
||||
// Therefore, the expression takes precedence to the name for the purpose of allow-list validation.
|
||||
return ! empty( $metric->getExpression() ) ? $metric->getExpression() : $metric->getName();
|
||||
},
|
||||
$metrics
|
||||
),
|
||||
$valid_metrics
|
||||
);
|
||||
|
||||
if ( count( $invalid_metrics ) > 0 ) {
|
||||
$message = count( $invalid_metrics ) > 1 ? sprintf(
|
||||
/* translators: %s: is replaced with a comma separated list of the invalid metrics. */
|
||||
__(
|
||||
'Unsupported metrics requested: %s',
|
||||
'google-site-kit'
|
||||
),
|
||||
join(
|
||||
/* translators: used between list items, there is a space after the comma. */
|
||||
__( ', ', 'google-site-kit' ),
|
||||
$invalid_metrics
|
||||
)
|
||||
) : sprintf(
|
||||
/* translators: %s: is replaced with the invalid metric. */
|
||||
__(
|
||||
'Unsupported metric requested: %s',
|
||||
'google-site-kit'
|
||||
),
|
||||
$invalid_metrics[0]
|
||||
);
|
||||
|
||||
throw new Invalid_Report_Metrics_Exception( $message );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the report dimensions for a shared request.
|
||||
*
|
||||
* @since 1.99.0
|
||||
*
|
||||
* @param Google_Service_AnalyticsData_Dimension[] $dimensions The dimensions to validate.
|
||||
* @throws Invalid_Report_Dimensions_Exception Thrown if the dimensions are invalid.
|
||||
*/
|
||||
protected function validate_shared_dimensions( $dimensions ) {
|
||||
$valid_dimensions = apply_filters(
|
||||
'googlesitekit_shareable_analytics_4_dimensions',
|
||||
array(
|
||||
'adSourceName',
|
||||
'city',
|
||||
'country',
|
||||
'date',
|
||||
'deviceCategory',
|
||||
'newVsReturning',
|
||||
'pagePath',
|
||||
'pageTitle',
|
||||
'sessionDefaultChannelGroup',
|
||||
'sessionDefaultChannelGrouping',
|
||||
'customEvent:googlesitekit_post_author',
|
||||
'customEvent:googlesitekit_post_categories',
|
||||
'customEvent:googlesitekit_post_date',
|
||||
'customEvent:googlesitekit_post_type',
|
||||
)
|
||||
);
|
||||
|
||||
$invalid_dimensions = array_diff(
|
||||
array_map(
|
||||
function ( $dimension ) {
|
||||
return $dimension->getName();
|
||||
},
|
||||
$dimensions
|
||||
),
|
||||
$valid_dimensions
|
||||
);
|
||||
|
||||
if ( count( $invalid_dimensions ) > 0 ) {
|
||||
$message = count( $invalid_dimensions ) > 1 ? sprintf(
|
||||
/* translators: %s: is replaced with a comma separated list of the invalid dimensions. */
|
||||
__(
|
||||
'Unsupported dimensions requested: %s',
|
||||
'google-site-kit'
|
||||
),
|
||||
join(
|
||||
/* translators: used between list items, there is a space after the comma. */
|
||||
__( ', ', 'google-site-kit' ),
|
||||
$invalid_dimensions
|
||||
)
|
||||
) : sprintf(
|
||||
/* translators: %s: is replaced with the invalid dimension. */
|
||||
__(
|
||||
'Unsupported dimension requested: %s',
|
||||
'google-site-kit'
|
||||
),
|
||||
$invalid_dimensions[0]
|
||||
);
|
||||
|
||||
throw new Invalid_Report_Dimensions_Exception( $message );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses dimension filters and returns a filter expression that should be added to the report request.
|
||||
*
|
||||
* @since 1.106.0
|
||||
*
|
||||
* @param Data_Request $data Data request object.
|
||||
* @return Google_Service_AnalyticsData_FilterExpression The filter expression to use with the report request.
|
||||
*/
|
||||
protected function parse_dimension_filters( Data_Request $data ) {
|
||||
$expressions = array();
|
||||
|
||||
$reference_url = trim( $this->context->get_reference_site_url(), '/' );
|
||||
$hostnames = URL::permute_site_hosts( URL::parse( $reference_url, PHP_URL_HOST ) );
|
||||
$expressions[] = $this->parse_dimension_filter( 'hostName', $hostnames );
|
||||
|
||||
if ( ! empty( $data['url'] ) ) {
|
||||
$url = str_replace( $reference_url, '', esc_url_raw( $data['url'] ) );
|
||||
$expressions[] = $this->parse_dimension_filter( 'pagePath', $url );
|
||||
}
|
||||
|
||||
if ( is_array( $data['dimensionFilters'] ) ) {
|
||||
foreach ( $data['dimensionFilters'] as $key => $value ) {
|
||||
$expressions[] = $this->parse_dimension_filter( $key, $value );
|
||||
}
|
||||
}
|
||||
|
||||
$filter_expression_list = new Google_Service_AnalyticsData_FilterExpressionList();
|
||||
$filter_expression_list->setExpressions( array_filter( $expressions ) );
|
||||
|
||||
$dimension_filters = new Google_Service_AnalyticsData_FilterExpression();
|
||||
$dimension_filters->setAndGroup( $filter_expression_list );
|
||||
|
||||
return $dimension_filters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses and returns a single dimension filter.
|
||||
*
|
||||
* @since 1.106.0
|
||||
*
|
||||
* @param string $dimension_name The dimension name.
|
||||
* @param mixed $dimension_value The dimension fileter settings.
|
||||
* @return Google_Service_AnalyticsData_FilterExpression The filter expression instance.
|
||||
*/
|
||||
protected function parse_dimension_filter( $dimension_name, $dimension_value ) {
|
||||
// Use the string filter type by default.
|
||||
$filter_type = 'stringFilter';
|
||||
if ( isset( $dimension_value['filterType'] ) ) {
|
||||
// If the filterType property is provided, use the explicit filter type then.
|
||||
$filter_type = $dimension_value['filterType'];
|
||||
} elseif ( wp_is_numeric_array( $dimension_value ) ) {
|
||||
// Otherwise, if the dimension has a numeric array of values, we should fall
|
||||
// back to the "in list" filter type.
|
||||
$filter_type = 'inListFilter';
|
||||
}
|
||||
|
||||
if ( 'stringFilter' === $filter_type ) {
|
||||
$filter_class = String_Filter::class;
|
||||
} elseif ( 'inListFilter' === $filter_type ) {
|
||||
$filter_class = In_List_Filter::class;
|
||||
// Ensure that the 'inListFilter' is provided a flat array of values.
|
||||
// Extract the actual values from the 'value' key if present.
|
||||
if ( isset( $dimension_value['value'] ) ) {
|
||||
$dimension_value = $dimension_value['value'];
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
$filter = new $filter_class();
|
||||
$filter_expression = $filter->parse_filter_expression( $dimension_name, $dimension_value );
|
||||
|
||||
if ( ! empty( $dimension_value['notExpression'] ) ) {
|
||||
$not_filter_expression = new Google_Service_AnalyticsData_FilterExpression();
|
||||
$not_filter_expression->setNotExpression( $filter_expression );
|
||||
return $not_filter_expression;
|
||||
}
|
||||
|
||||
return $filter_expression;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses metric filters and returns a filter expression that should be added to the report request.
|
||||
*
|
||||
* @since 1.111.0
|
||||
*
|
||||
* @param Data_Request $data Data request object.
|
||||
* @return Google_Service_AnalyticsData_FilterExpression The filter expression to use with the report request.
|
||||
*/
|
||||
protected function parse_metric_filters( Data_Request $data ) {
|
||||
$expressions = array();
|
||||
|
||||
if ( is_array( $data['metricFilters'] ) ) {
|
||||
foreach ( $data['metricFilters'] as $key => $value ) {
|
||||
$expressions[] = $this->parse_metric_filter( $key, $value );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty( $expressions ) ) {
|
||||
$filter_expression_list = new Google_Service_AnalyticsData_FilterExpressionList();
|
||||
$filter_expression_list->setExpressions( array_filter( $expressions ) );
|
||||
|
||||
$metric_filters = new Google_Service_AnalyticsData_FilterExpression();
|
||||
$metric_filters->setAndGroup( $filter_expression_list );
|
||||
|
||||
return $metric_filters;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses and returns a single metric filter.
|
||||
*
|
||||
* @since 1.111.0
|
||||
*
|
||||
* @param string $metric_name The metric name.
|
||||
* @param mixed $metric_value The metric filter settings.
|
||||
* @return Google_Service_AnalyticsData_FilterExpression The filter expression instance.
|
||||
*/
|
||||
protected function parse_metric_filter( $metric_name, $metric_value ) {
|
||||
// Use the numeric filter type by default.
|
||||
$filter_type = 'numericFilter';
|
||||
if ( isset( $metric_value['filterType'] ) ) {
|
||||
// If the filterType property is provided, use the explicit filter type then.
|
||||
$filter_type = $metric_value['filterType'];
|
||||
}
|
||||
|
||||
if ( 'numericFilter' === $filter_type ) {
|
||||
if ( ! isset( $metric_value['operation'] ) || ! isset( $metric_value['value'] ) ) {
|
||||
return null;
|
||||
}
|
||||
if ( ! isset( $metric_value['value']['int64Value'] ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$filter = new Numeric_Filter();
|
||||
|
||||
} elseif ( 'betweenFilter' === $filter_type ) {
|
||||
if ( ! isset( $metric_value['from_value'] ) || ! isset( $metric_value['to_value'] ) ) {
|
||||
return null;
|
||||
}
|
||||
if (
|
||||
! isset( $metric_value['from_value']['int64Value'] ) ||
|
||||
! isset( $metric_value['to_value']['int64Value'] )
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$filter = new Between_Filter();
|
||||
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
$filter_expression = $this->get_metric_filter_expression(
|
||||
$filter,
|
||||
$metric_name,
|
||||
$metric_value
|
||||
);
|
||||
|
||||
return $filter_expression;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns correct filter expression instance based on the metric filter instance.
|
||||
*
|
||||
* @since 1.111.0
|
||||
*
|
||||
* @param Numeric_Filter|Between_Filter $filter The metric filter instance.
|
||||
* @param string $metric_name The metric name.
|
||||
* @param mixed $metric_value The metric filter settings.
|
||||
* @return Google_Service_AnalyticsData_FilterExpression The filter expression instance.
|
||||
*/
|
||||
protected function get_metric_filter_expression( $filter, $metric_name, $metric_value ) {
|
||||
if ( $filter instanceof Numeric_Filter ) {
|
||||
$value = $metric_value['value']['int64Value'];
|
||||
|
||||
$filter_expression = $filter->parse_filter_expression(
|
||||
$metric_name,
|
||||
$metric_value['operation'],
|
||||
$value
|
||||
);
|
||||
|
||||
} elseif ( $filter instanceof Between_Filter ) {
|
||||
$from_value = $metric_value['from_value']['int64Value'];
|
||||
$to_value = $metric_value['to_value']['int64Value'];
|
||||
|
||||
$filter_expression = $filter->parse_filter_expression(
|
||||
$metric_name,
|
||||
$from_value,
|
||||
$to_value
|
||||
);
|
||||
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $filter_expression;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,231 @@
|
||||
<?php
|
||||
/**
|
||||
* Class Google\Site_Kit\Modules\Analytics_4\Report\Response
|
||||
*
|
||||
* @package Google\Site_Kit\Modules\Analytics_4\Report
|
||||
* @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\Report;
|
||||
|
||||
use Google\Site_Kit\Core\REST_API\Data_Request;
|
||||
use Google\Site_Kit\Modules\Analytics_4\Report;
|
||||
use Google\Site_Kit_Dependencies\Google\Service\AnalyticsData\DateRange as Google_Service_AnalyticsData_DateRange;
|
||||
use Google\Site_Kit_Dependencies\Google\Service\AnalyticsData\Row as Google_Service_AnalyticsData_Row;
|
||||
use Google\Site_Kit_Dependencies\Google\Service\AnalyticsData\RunReportResponse as Google_Service_AnalyticsData_RunReportResponse;
|
||||
|
||||
/**
|
||||
* Class for Analytics 4 report responses.
|
||||
*
|
||||
* @since 1.99.0
|
||||
* @access private
|
||||
* @ignore
|
||||
*/
|
||||
class Response extends Report {
|
||||
|
||||
use Row_Trait;
|
||||
|
||||
/**
|
||||
* Parses the report response, and pads the report data with zero-data rows where rows are missing. This only applies for reports which request a single `date` dimension.
|
||||
*
|
||||
* @since 1.99.0
|
||||
*
|
||||
* @param Data_Request $data Data request object.
|
||||
* @param Google_Service_AnalyticsData_RunReportResponse $response Request response.
|
||||
* @return mixed Parsed response data on success, or WP_Error on failure.
|
||||
*/
|
||||
public function parse_response( Data_Request $data, $response ) {
|
||||
// Return early if the response is not of the expected type.
|
||||
if ( ! $response instanceof Google_Service_AnalyticsData_RunReportResponse ) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
// Get report dimensions and return early if there is either more than one dimension or
|
||||
// the only dimension is not "date".
|
||||
$dimensions = $this->parse_dimensions( $data );
|
||||
if ( count( $dimensions ) !== 1 || $dimensions[0]->getName() !== 'date' ) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
// Get date ranges and return early if there are no date ranges for this report.
|
||||
$date_ranges = $this->get_sorted_dateranges( $data );
|
||||
if ( empty( $date_ranges ) ) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
// Get all available dates in the report.
|
||||
$existing_rows = array();
|
||||
foreach ( $response->getRows() as $row ) {
|
||||
$dimension_values = $row->getDimensionValues();
|
||||
|
||||
$range = 'date_range_0';
|
||||
if ( count( $dimension_values ) > 1 ) {
|
||||
// Considering this code will only be run when we are requesting a single dimension, `date`,
|
||||
// the implication is that the row will _only_ have an additional dimension when multiple
|
||||
// date ranges are requested.
|
||||
//
|
||||
// In this scenario, the dimension at index 1 will have a value of `date_range_{i}`, where
|
||||
// `i` is the zero-based index of the date range.
|
||||
$range = $dimension_values[1]->getValue();
|
||||
}
|
||||
|
||||
$range = str_replace( 'date_range_', '', $range );
|
||||
$date = $dimension_values[0]->getValue();
|
||||
$key = self::get_response_row_key( $date, is_numeric( $range ) ? $range : false );
|
||||
|
||||
$existing_rows[ $key ] = $row;
|
||||
}
|
||||
|
||||
$metric_headers = $response->getMetricHeaders();
|
||||
$ranges_count = count( $date_ranges );
|
||||
$multiple_ranges = $ranges_count > 1;
|
||||
$rows = array();
|
||||
|
||||
// Add rows for the current date for each date range.
|
||||
self::iterate_date_ranges(
|
||||
$date_ranges,
|
||||
function( $date ) use ( &$rows, $existing_rows, $ranges_count, $metric_headers, $multiple_ranges ) {
|
||||
for ( $i = 0; $i < $ranges_count; $i++ ) {
|
||||
// Copy the existing row if it is available, otherwise create a new zero-value row.
|
||||
$key = self::get_response_row_key( $date, $i );
|
||||
$rows[ $key ] = isset( $existing_rows[ $key ] )
|
||||
? $existing_rows[ $key ]
|
||||
: $this->create_report_row( $metric_headers, $date, $multiple_ranges ? $i : false );
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// If we have the same number of rows as in the response at the moment, then
|
||||
// we can return the response without setting the new rows back into the response.
|
||||
$new_rows_count = count( $rows );
|
||||
if ( $new_rows_count <= $response->getRowCount() ) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
// If we have multiple date ranges, we need to sort rows to have them in
|
||||
// the correct order.
|
||||
if ( $multiple_ranges ) {
|
||||
$rows = self::sort_response_rows( $rows, $date_ranges );
|
||||
}
|
||||
|
||||
// Set updated rows back to the response object.
|
||||
$response->setRows( array_values( $rows ) );
|
||||
$response->setRowCount( $new_rows_count );
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the response row key composed from the date and the date range index values.
|
||||
*
|
||||
* @since 1.99.0
|
||||
*
|
||||
* @param string $date The date of the row to return key for.
|
||||
* @param int|bool $date_range_index The date range index, or FALSE if no index is available.
|
||||
* @return string The row key.
|
||||
*/
|
||||
protected static function get_response_row_key( $date, $date_range_index ) {
|
||||
return "{$date}_{$date_range_index}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns sorted and filtered date ranges received in the request params. All corrupted date ranges
|
||||
* are ignored and not included in the returning list.
|
||||
*
|
||||
* @since 1.99.0
|
||||
*
|
||||
* @param Data_Request $data Data request object.
|
||||
* @return Google_Service_AnalyticsData_DateRange[] An array of AnalyticsData DateRange objects.
|
||||
*/
|
||||
protected function get_sorted_dateranges( Data_Request $data ) {
|
||||
$date_ranges = $this->parse_dateranges( $data );
|
||||
if ( empty( $date_ranges ) ) {
|
||||
return $date_ranges;
|
||||
}
|
||||
|
||||
// Filter out all corrupted date ranges.
|
||||
$date_ranges = array_filter(
|
||||
$date_ranges,
|
||||
function( $range ) {
|
||||
$start = strtotime( $range->getStartDate() );
|
||||
$end = strtotime( $range->getEndDate() );
|
||||
return ! empty( $start ) && ! empty( $end );
|
||||
}
|
||||
);
|
||||
|
||||
// Sort date ranges preserving keys to have the oldest date range at the beginning and
|
||||
// the latest date range at the end.
|
||||
uasort(
|
||||
$date_ranges,
|
||||
function( $a, $b ) {
|
||||
$a_start = strtotime( $a->getStartDate() );
|
||||
$b_start = strtotime( $b->getStartDate() );
|
||||
return $a_start - $b_start;
|
||||
}
|
||||
);
|
||||
|
||||
return $date_ranges;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts response rows using the algorithm similar to the one that Analytics 4 uses internally
|
||||
* and returns sorted rows.
|
||||
*
|
||||
* @since 1.99.0
|
||||
*
|
||||
* @param Google_Service_AnalyticsData_Row[] $rows The current report rows.
|
||||
* @param Google_Service_AnalyticsData_DateRange[] $date_ranges The report date ranges.
|
||||
* @return Google_Service_AnalyticsData_Row[] Sorted rows.
|
||||
*/
|
||||
protected static function sort_response_rows( $rows, $date_ranges ) {
|
||||
$sorted_rows = array();
|
||||
$ranges_count = count( $date_ranges );
|
||||
|
||||
self::iterate_date_ranges(
|
||||
$date_ranges,
|
||||
function( $date, $range_index ) use ( &$sorted_rows, $ranges_count, $rows ) {
|
||||
// First take the main date range row.
|
||||
$key = self::get_response_row_key( $date, $range_index );
|
||||
$sorted_rows[ $key ] = $rows[ $key ];
|
||||
|
||||
// Then take all remaining rows.
|
||||
for ( $i = 0; $i < $ranges_count; $i++ ) {
|
||||
if ( $i !== $range_index ) {
|
||||
$key = self::get_response_row_key( $date, $i );
|
||||
$sorted_rows[ $key ] = $rows[ $key ];
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
return $sorted_rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates over the date ranges and calls callback for each date in each range.
|
||||
*
|
||||
* @since 1.99.0
|
||||
*
|
||||
* @param Google_Service_AnalyticsData_DateRange[] $date_ranges The report date ranges.
|
||||
* @param callable $callback The callback to execute for each date.
|
||||
*/
|
||||
protected static function iterate_date_ranges( $date_ranges, $callback ) {
|
||||
foreach ( $date_ranges as $date_range_index => $date_range ) {
|
||||
$now = strtotime( $date_range->getStartDate() );
|
||||
$end = strtotime( $date_range->getEndDate() );
|
||||
|
||||
do {
|
||||
call_user_func(
|
||||
$callback,
|
||||
gmdate( 'Ymd', $now ),
|
||||
$date_range_index
|
||||
);
|
||||
|
||||
$now += DAY_IN_SECONDS;
|
||||
} while ( $now <= $end );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
/**
|
||||
* Class Google\Site_Kit\Modules\Analytics_4\Report\Row_Trait
|
||||
*
|
||||
* @package Google\Site_Kit\Modules\Analytics_4\Report
|
||||
* @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\Report;
|
||||
|
||||
use Google\Site_Kit_Dependencies\Google\Service\AnalyticsData\DimensionValue as Google_Service_AnalyticsData_DimensionValue;
|
||||
use Google\Site_Kit_Dependencies\Google\Service\AnalyticsData\MetricHeader as Google_Service_AnalyticsData_MetricHeader;
|
||||
use Google\Site_Kit_Dependencies\Google\Service\AnalyticsData\MetricValue as Google_Service_AnalyticsData_MetricValue;
|
||||
use Google\Site_Kit_Dependencies\Google\Service\AnalyticsData\Row as Google_Service_AnalyticsData_Row;
|
||||
|
||||
/**
|
||||
* A trait that adds a helper method to create report rows.
|
||||
*
|
||||
* @since 1.99.0
|
||||
* @access private
|
||||
* @ignore
|
||||
*/
|
||||
trait Row_Trait {
|
||||
|
||||
/**
|
||||
* Creates and returns a new zero-value row for provided date and metrics.
|
||||
*
|
||||
* @since 1.99.0
|
||||
*
|
||||
* @param Google_Service_AnalyticsData_MetricHeader[] $metric_headers Metric headers from the report response.
|
||||
* @param string $current_date The current date to create a zero-value row for.
|
||||
* @param int|bool $date_range_index The date range index for the current date.
|
||||
* @param string $default_value The default value to use for metric values in the row.
|
||||
* @return Google_Service_AnalyticsData_Row A new zero-value row instance.
|
||||
*/
|
||||
protected function create_report_row( $metric_headers, $current_date, $date_range_index, $default_value = '0' ) {
|
||||
$dimension_values = array();
|
||||
|
||||
$current_date_dimension_value = new Google_Service_AnalyticsData_DimensionValue();
|
||||
$current_date_dimension_value->setValue( $current_date );
|
||||
$dimension_values[] = $current_date_dimension_value;
|
||||
|
||||
// If we have multiple date ranges, we need to add "date_range_{i}" index to dimension values.
|
||||
if ( false !== $date_range_index ) {
|
||||
$date_range_dimension_value = new Google_Service_AnalyticsData_DimensionValue();
|
||||
$date_range_dimension_value->setValue( "date_range_{$date_range_index}" );
|
||||
$dimension_values[] = $date_range_dimension_value;
|
||||
}
|
||||
|
||||
$metric_values = array();
|
||||
foreach ( $metric_headers as $metric_header ) {
|
||||
$metric_value = new Google_Service_AnalyticsData_MetricValue();
|
||||
$metric_value->setValue( $default_value );
|
||||
|
||||
$metric_values[] = $metric_value;
|
||||
}
|
||||
|
||||
$row = new Google_Service_AnalyticsData_Row();
|
||||
$row->setDimensionValues( $dimension_values );
|
||||
$row->setMetricValues( $metric_values );
|
||||
|
||||
return $row;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,253 @@
|
||||
<?php
|
||||
/**
|
||||
* Class Google\Site_Kit\Modules\Analytics_4\Resource_Data_Availability_Date
|
||||
*
|
||||
* @package Google\Site_Kit\Modules\Analytics_4
|
||||
* @copyright 2024 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;
|
||||
|
||||
use Google\Site_Kit\Core\Modules\Module_Settings;
|
||||
use Google\Site_Kit\Core\Storage\Transients;
|
||||
|
||||
/**
|
||||
* Class for managing Analytics 4 resource data availability date.
|
||||
*
|
||||
* @since 1.127.0
|
||||
* @access private
|
||||
* @ignore
|
||||
*/
|
||||
class Resource_Data_Availability_Date {
|
||||
|
||||
/**
|
||||
* List of valid custom dimension slugs.
|
||||
*
|
||||
* @since 1.127.0
|
||||
* @var array
|
||||
*/
|
||||
const CUSTOM_DIMENSION_SLUGS = array(
|
||||
'googlesitekit_post_type',
|
||||
);
|
||||
|
||||
const RESOURCE_TYPE_AUDIENCE = 'audience';
|
||||
const RESOURCE_TYPE_CUSTOM_DIMENSION = 'customDimension';
|
||||
const RESOURCE_TYPE_PROPERTY = 'property';
|
||||
|
||||
/**
|
||||
* Transients instance.
|
||||
*
|
||||
* @since 1.127.0
|
||||
* @var Transients
|
||||
*/
|
||||
protected $transients;
|
||||
|
||||
/**
|
||||
* Module settings.
|
||||
*
|
||||
* @since 1.127.0
|
||||
* @var Module_Settings
|
||||
*/
|
||||
protected $settings;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @since 1.127.0
|
||||
*
|
||||
* @param Transients $transients Transients instance.
|
||||
* @param Module_Settings $settings Module settings instance.
|
||||
*/
|
||||
public function __construct( Transients $transients, Module_Settings $settings ) {
|
||||
$this->transients = $transients;
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the data availability date for the given resource.
|
||||
*
|
||||
* @since 1.127.0
|
||||
*
|
||||
* @param string $resource_slug Resource slug.
|
||||
* @param string $resource_type Resource type.
|
||||
* @return int Data availability date in YYYYMMDD format on success, 0 otherwise.
|
||||
*/
|
||||
public function get_resource_date( $resource_slug, $resource_type ) {
|
||||
return (int) $this->transients->get( $this->get_resource_transient_name( $resource_slug, $resource_type ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the data availability date for the given resource.
|
||||
*
|
||||
* @since 1.127.0
|
||||
*
|
||||
* @param string $resource_slug Resource slug.
|
||||
* @param string $resource_type Resource type.
|
||||
* @param int $date Data availability date.
|
||||
* @return bool True on success, false otherwise.
|
||||
*/
|
||||
public function set_resource_date( $resource_slug, $resource_type, $date ) {
|
||||
return $this->transients->set( $this->get_resource_transient_name( $resource_slug, $resource_type ), $date );
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the data availability date for the given resource.
|
||||
*
|
||||
* @since 1.127.0
|
||||
*
|
||||
* @param string $resource_slug Resource slug.
|
||||
* @param string $resource_type Resource type.
|
||||
* @return bool True on success, false otherwise.
|
||||
*/
|
||||
public function reset_resource_date( $resource_slug, $resource_type ) {
|
||||
return $this->transients->delete( $this->get_resource_transient_name( $resource_slug, $resource_type ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data availability dates for all resources.
|
||||
*
|
||||
* @since 1.127.0
|
||||
*
|
||||
* @return array Associative array of resource names and their data availability date.
|
||||
*/
|
||||
public function get_all_resource_dates() {
|
||||
$property_id = $this->get_property_id();
|
||||
$available_audiences = $this->get_available_audience_resource_names();
|
||||
|
||||
return array_map(
|
||||
// Filter out falsy values (0) from every resource's data availability dates.
|
||||
fn( $data_availability_dates ) => array_filter( $data_availability_dates ),
|
||||
array(
|
||||
// Get data availability dates for the available audiences.
|
||||
self::RESOURCE_TYPE_AUDIENCE => array_reduce(
|
||||
$available_audiences,
|
||||
function ( $audience_data_availability_dates, $audience ) {
|
||||
$audience_data_availability_dates[ $audience ] = $this->get_resource_date( $audience, self::RESOURCE_TYPE_AUDIENCE );
|
||||
return $audience_data_availability_dates;
|
||||
},
|
||||
array()
|
||||
),
|
||||
// Get data availability dates for the custom dimensions.
|
||||
self::RESOURCE_TYPE_CUSTOM_DIMENSION => array_reduce(
|
||||
self::CUSTOM_DIMENSION_SLUGS,
|
||||
function ( $custom_dimension_data_availability_dates, $custom_dimension ) {
|
||||
$custom_dimension_data_availability_dates[ $custom_dimension ] = $this->get_resource_date( $custom_dimension, self::RESOURCE_TYPE_CUSTOM_DIMENSION );
|
||||
return $custom_dimension_data_availability_dates;
|
||||
},
|
||||
array()
|
||||
),
|
||||
// Get data availability date for the current property.
|
||||
self::RESOURCE_TYPE_PROPERTY => array(
|
||||
$property_id => $this->get_resource_date(
|
||||
$property_id,
|
||||
self::RESOURCE_TYPE_PROPERTY
|
||||
),
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the data availability date for all resources.
|
||||
*
|
||||
* @since 1.127.0
|
||||
*
|
||||
* @param array/null $available_audience_names Optional. List of available audience resource names. If not provided, it will be fetched from settings.
|
||||
* @param string/null $property_id Optional. Property ID. If not provided, it will be fetched from settings.
|
||||
*/
|
||||
public function reset_all_resource_dates( $available_audience_names = null, $property_id = null ) {
|
||||
|
||||
foreach ( self::CUSTOM_DIMENSION_SLUGS as $custom_dimension ) {
|
||||
$this->reset_resource_date( $custom_dimension, self::RESOURCE_TYPE_CUSTOM_DIMENSION );
|
||||
}
|
||||
|
||||
$available_audience_names = $available_audience_names ?: $this->get_available_audience_resource_names();
|
||||
|
||||
foreach ( $available_audience_names as $audience_name ) {
|
||||
$this->reset_resource_date( $audience_name, self::RESOURCE_TYPE_AUDIENCE );
|
||||
}
|
||||
|
||||
$property_id = $property_id ?: $this->get_property_id();
|
||||
|
||||
$this->reset_resource_date( $property_id, self::RESOURCE_TYPE_PROPERTY );
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given resource type is valid.
|
||||
*
|
||||
* @since 1.127.0
|
||||
*
|
||||
* @param string $resource_type Resource type.
|
||||
* @return bool True if valid, false otherwise.
|
||||
*/
|
||||
public function is_valid_resource_type( $resource_type ) {
|
||||
return in_array( $resource_type, array( self::RESOURCE_TYPE_AUDIENCE, self::RESOURCE_TYPE_CUSTOM_DIMENSION, self::RESOURCE_TYPE_PROPERTY ), true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given resource slug is valid.
|
||||
*
|
||||
* @since 1.127.0
|
||||
*
|
||||
* @param string $resource_slug Resource slug.
|
||||
* @param string $resource_type Resource type.
|
||||
* @return bool True if valid, false otherwise.
|
||||
*/
|
||||
public function is_valid_resource_slug( $resource_slug, $resource_type ) {
|
||||
switch ( $resource_type ) {
|
||||
case self::RESOURCE_TYPE_AUDIENCE:
|
||||
return in_array( $resource_slug, $this->get_available_audience_resource_names(), true );
|
||||
case self::RESOURCE_TYPE_CUSTOM_DIMENSION:
|
||||
return in_array( $resource_slug, self::CUSTOM_DIMENSION_SLUGS, true );
|
||||
case self::RESOURCE_TYPE_PROPERTY:
|
||||
return $resource_slug === $this->get_property_id();
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data available date transient name for the given resource.
|
||||
*
|
||||
* @since 1.127.0
|
||||
*
|
||||
* @param string $resource_slug Resource slug.
|
||||
* @param string $resource_type Resource type.
|
||||
* @return string Data available date transient name.
|
||||
*/
|
||||
protected function get_resource_transient_name( $resource_slug, $resource_type ) {
|
||||
return "googlesitekit_{$resource_type}_{$resource_slug}_data_availability_date";
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets available audience resource names.
|
||||
*
|
||||
* @since 1.127.0
|
||||
*
|
||||
* @return array List of available audience resource names.
|
||||
*/
|
||||
private function get_available_audience_resource_names() {
|
||||
$settings = $this->settings->get();
|
||||
$available_audiences = $settings['availableAudiences'] ?? array();
|
||||
|
||||
return array_map(
|
||||
function ( $audience ) {
|
||||
return $audience['name'];
|
||||
},
|
||||
$available_audiences
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the property ID from settings instance.
|
||||
*
|
||||
* @since 1.127.0
|
||||
*
|
||||
* @return string Property ID.
|
||||
*/
|
||||
private function get_property_id() {
|
||||
return $this->settings->get()['propertyID'];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,207 @@
|
||||
<?php
|
||||
/**
|
||||
* Class Google\Site_Kit\Modules\Analytics_4\Settings
|
||||
*
|
||||
* @package Google\Site_Kit\Modules\Analytics_4
|
||||
* @copyright 2021 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;
|
||||
|
||||
use Google\Site_Kit\Core\Modules\Module_Settings;
|
||||
use Google\Site_Kit\Core\Storage\Setting_With_Owned_Keys_Interface;
|
||||
use Google\Site_Kit\Core\Storage\Setting_With_Owned_Keys_Trait;
|
||||
use Google\Site_Kit\Core\Storage\Setting_With_ViewOnly_Keys_Interface;
|
||||
use Google\Site_Kit\Core\Util\Method_Proxy_Trait;
|
||||
|
||||
/**
|
||||
* Class for Analytics 4 settings.
|
||||
*
|
||||
* @since 1.30.0
|
||||
* @access private
|
||||
* @ignore
|
||||
*/
|
||||
class Settings extends Module_Settings implements Setting_With_Owned_Keys_Interface, Setting_With_ViewOnly_Keys_Interface {
|
||||
|
||||
use Setting_With_Owned_Keys_Trait;
|
||||
use Method_Proxy_Trait;
|
||||
|
||||
const OPTION = 'googlesitekit_analytics-4_settings';
|
||||
|
||||
/**
|
||||
* Registers the setting in WordPress.
|
||||
*
|
||||
* @since 1.30.0
|
||||
*/
|
||||
public function register() {
|
||||
parent::register();
|
||||
|
||||
$this->register_owned_keys();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns keys for owned settings.
|
||||
*
|
||||
* @since 1.30.0
|
||||
*
|
||||
* @return array An array of keys for owned settings.
|
||||
*/
|
||||
public function get_owned_keys() {
|
||||
return array(
|
||||
'accountID',
|
||||
'propertyID',
|
||||
'webDataStreamID',
|
||||
'measurementID',
|
||||
'googleTagID',
|
||||
'googleTagAccountID',
|
||||
'googleTagContainerID',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns keys for view-only settings.
|
||||
*
|
||||
* @since 1.113.0
|
||||
*
|
||||
* @return array An array of keys for view-only settings.
|
||||
*/
|
||||
public function get_view_only_keys() {
|
||||
return array( 'availableCustomDimensions', 'adSenseLinked' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the default value.
|
||||
*
|
||||
* @since 1.30.0
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function get_default() {
|
||||
return array(
|
||||
'ownerID' => 0,
|
||||
'accountID' => '',
|
||||
'adsConversionID' => '',
|
||||
'propertyID' => '',
|
||||
'webDataStreamID' => '',
|
||||
'measurementID' => '',
|
||||
'trackingDisabled' => array( 'loggedinUsers' ),
|
||||
'useSnippet' => true,
|
||||
'googleTagID' => '',
|
||||
'googleTagAccountID' => '',
|
||||
'googleTagContainerID' => '',
|
||||
'googleTagContainerDestinationIDs' => null,
|
||||
'googleTagLastSyncedAtMs' => 0,
|
||||
'availableCustomDimensions' => null,
|
||||
'propertyCreateTime' => 0,
|
||||
'adSenseLinked' => false,
|
||||
'adSenseLinkedLastSyncedAt' => 0,
|
||||
'adsConversionIDMigratedAtMs' => 0,
|
||||
'adsLinked' => false,
|
||||
'adsLinkedLastSyncedAt' => 0,
|
||||
'availableAudiences' => null,
|
||||
'availableAudiencesLastSyncedAt' => 0,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the callback for sanitizing the setting's value before saving.
|
||||
*
|
||||
* @since 1.30.0
|
||||
*
|
||||
* @return callable|null
|
||||
*/
|
||||
protected function get_sanitize_callback() {
|
||||
return function( $option ) {
|
||||
if ( is_array( $option ) ) {
|
||||
if ( isset( $option['useSnippet'] ) ) {
|
||||
$option['useSnippet'] = (bool) $option['useSnippet'];
|
||||
}
|
||||
if ( isset( $option['googleTagID'] ) ) {
|
||||
if ( ! preg_match( '/^(G|GT|AW)-[a-zA-Z0-9]+$/', $option['googleTagID'] ) ) {
|
||||
$option['googleTagID'] = '';
|
||||
}
|
||||
}
|
||||
if ( isset( $option['trackingDisabled'] ) ) {
|
||||
// Prevent other options from being saved if 'loggedinUsers' is selected.
|
||||
if ( in_array( 'loggedinUsers', $option['trackingDisabled'], true ) ) {
|
||||
$option['trackingDisabled'] = array( 'loggedinUsers' );
|
||||
} else {
|
||||
$option['trackingDisabled'] = (array) $option['trackingDisabled'];
|
||||
}
|
||||
}
|
||||
|
||||
$numeric_properties = array( 'googleTagAccountID', 'googleTagContainerID' );
|
||||
foreach ( $numeric_properties as $numeric_property ) {
|
||||
if ( isset( $option[ $numeric_property ] ) ) {
|
||||
if ( ! is_numeric( $option[ $numeric_property ] ) || ! $option[ $numeric_property ] > 0 ) {
|
||||
$option[ $numeric_property ] = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $option['googleTagContainerDestinationIDs'] ) ) {
|
||||
if ( ! is_array( $option['googleTagContainerDestinationIDs'] ) ) {
|
||||
$option['googleTagContainerDestinationIDs'] = null;
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $option['availableCustomDimensions'] ) ) {
|
||||
if ( is_array( $option['availableCustomDimensions'] ) ) {
|
||||
$valid_dimensions = array_filter(
|
||||
$option['availableCustomDimensions'],
|
||||
function( $dimension ) {
|
||||
return is_string( $dimension ) && strpos( $dimension, 'googlesitekit_' ) === 0;
|
||||
}
|
||||
);
|
||||
|
||||
$option['availableCustomDimensions'] = array_values( $valid_dimensions );
|
||||
} else {
|
||||
$option['availableCustomDimensions'] = null;
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $option['adSenseLinked'] ) ) {
|
||||
$option['adSenseLinked'] = (bool) $option['adSenseLinked'];
|
||||
}
|
||||
|
||||
if ( isset( $option['adSenseLinkedLastSyncedAt'] ) ) {
|
||||
if ( ! is_int( $option['adSenseLinkedLastSyncedAt'] ) ) {
|
||||
$option['adSenseLinkedLastSyncedAt'] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $option['adsConversionIDMigratedAtMs'] ) ) {
|
||||
if ( ! is_int( $option['adsConversionIDMigratedAtMs'] ) ) {
|
||||
$option['adsConversionIDMigratedAtMs'] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $option['adsLinked'] ) ) {
|
||||
$option['adsLinked'] = (bool) $option['adsLinked'];
|
||||
}
|
||||
|
||||
if ( isset( $option['adsLinkedLastSyncedAt'] ) ) {
|
||||
if ( ! is_int( $option['adsLinkedLastSyncedAt'] ) ) {
|
||||
$option['adsLinkedLastSyncedAt'] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $option['availableAudiences'] ) ) {
|
||||
if ( ! is_array( $option['availableAudiences'] ) ) {
|
||||
$option['availableAudiences'] = null;
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $option['availableAudiencesLastSyncedAt'] ) ) {
|
||||
if ( ! is_int( $option['availableAudiencesLastSyncedAt'] ) ) {
|
||||
$option['availableAudiencesLastSyncedAt'] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $option;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
<?php
|
||||
/**
|
||||
* Class Google\Site_Kit\Modules\Analytics_4\Synchronize_AdSenseLinked
|
||||
*
|
||||
* @package Google\Site_Kit\Modules\Analytics_4
|
||||
* @copyright 2024 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;
|
||||
|
||||
use Google\Site_Kit\Core\Permissions\Permissions;
|
||||
use Google\Site_Kit\Core\Storage\Options;
|
||||
use Google\Site_Kit\Core\Storage\User_Options;
|
||||
use Google\Site_Kit\Modules\Adsense;
|
||||
use Google\Site_Kit\Modules\Analytics_4;
|
||||
use Google\Site_Kit\Modules\AdSense\Settings as Adsense_Settings;
|
||||
|
||||
/**
|
||||
* The base class for Synchronizing the adSenseLinked status.
|
||||
*
|
||||
* @since 1.123.0
|
||||
* @access private
|
||||
* @ignore
|
||||
*/
|
||||
class Synchronize_AdSenseLinked {
|
||||
const CRON_SYNCHRONIZE_ADSENSE_LINKED = 'googlesitekit_cron_synchronize_adsense_linked_data';
|
||||
|
||||
/**
|
||||
* Analytics_4 instance.
|
||||
*
|
||||
* @since 1.123.0
|
||||
* @var Analytics_4
|
||||
*/
|
||||
protected $analytics_4;
|
||||
|
||||
/**
|
||||
* User_Options instance.
|
||||
*
|
||||
* @since 1.123.0
|
||||
* @var User_Options
|
||||
*/
|
||||
protected $user_options;
|
||||
|
||||
/**
|
||||
* Options instance.
|
||||
*
|
||||
* @since 1.123.0
|
||||
* @var Options
|
||||
*/
|
||||
protected $options;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @since 1.123.0
|
||||
*
|
||||
* @param Analytics_4 $analytics_4 Analytics 4 instance.
|
||||
* @param User_Options $user_options User_Options instance.
|
||||
* @param Options $options Options instance.
|
||||
*/
|
||||
public function __construct( Analytics_4 $analytics_4, User_Options $user_options, Options $options ) {
|
||||
$this->analytics_4 = $analytics_4;
|
||||
$this->user_options = $user_options;
|
||||
$this->options = $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers functionality through WordPress hooks.
|
||||
*
|
||||
* @since 1.123.0
|
||||
*/
|
||||
public function register() {
|
||||
add_action(
|
||||
self::CRON_SYNCHRONIZE_ADSENSE_LINKED,
|
||||
function() {
|
||||
$this->synchronize_adsense_linked_data();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cron callback for synchronizing the adsense linked data.
|
||||
*
|
||||
* @since 1.123.0
|
||||
*/
|
||||
protected function synchronize_adsense_linked_data() {
|
||||
$owner_id = $this->analytics_4->get_owner_id();
|
||||
$restore_user = $this->user_options->switch_user( $owner_id );
|
||||
|
||||
if ( user_can( $owner_id, Permissions::VIEW_AUTHENTICATED_DASHBOARD ) ) {
|
||||
$this->synchronize_adsense_linked_status();
|
||||
}
|
||||
|
||||
$restore_user();
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules single cron which will synchronize the adSenseLinked status.
|
||||
*
|
||||
* @since 1.123.0
|
||||
*/
|
||||
public function maybe_schedule_synchronize_adsense_linked() {
|
||||
$analytics_4_connected = apply_filters( 'googlesitekit_is_module_connected', false, Analytics_4::MODULE_SLUG );
|
||||
$adsense_connected = apply_filters( 'googlesitekit_is_module_connected', false, AdSense::MODULE_SLUG );
|
||||
$cron_already_scheduled = wp_next_scheduled( self::CRON_SYNCHRONIZE_ADSENSE_LINKED );
|
||||
|
||||
if ( $analytics_4_connected && $adsense_connected && ! $cron_already_scheduled ) {
|
||||
wp_schedule_single_event(
|
||||
// Schedule the task to run in 24 hours.
|
||||
time() + ( DAY_IN_SECONDS ),
|
||||
self::CRON_SYNCHRONIZE_ADSENSE_LINKED
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronize the AdSenseLinked status.
|
||||
*
|
||||
* @since 1.123.0
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
protected function synchronize_adsense_linked_status() {
|
||||
$settings_ga4 = $this->analytics_4->get_settings()->get();
|
||||
$property_id = $settings_ga4['propertyID'];
|
||||
$property_adsense_links = $this->analytics_4->get_data( 'adsense-links', array( 'propertyID' => $property_id ) );
|
||||
$current_adsense_options = ( new AdSense_Settings( $this->options ) )->get();
|
||||
$current_adsense_client_id = ! empty( $current_adsense_options['clientID'] ) ? $current_adsense_options['clientID'] : '';
|
||||
|
||||
if ( is_wp_error( $property_adsense_links ) || empty( $property_adsense_links ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$found_adsense_linked_for_client_id = false;
|
||||
|
||||
// Iterate over returned AdSense links and set true if one is found
|
||||
// matching the same client ID.
|
||||
foreach ( $property_adsense_links as $property_adsense_link ) {
|
||||
if ( $current_adsense_client_id === $property_adsense_link['adClientCode'] ) {
|
||||
$found_adsense_linked_for_client_id = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Update the AdSenseLinked status and timestamp.
|
||||
$this->analytics_4->get_settings()->merge(
|
||||
array(
|
||||
'adSenseLinked' => $found_adsense_linked_for_client_id,
|
||||
'adSenseLinkedLastSyncedAt' => time(),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
<?php
|
||||
/**
|
||||
* Class Google\Site_Kit\Modules\Analytics_4\Synchronize_AdsLinked
|
||||
*
|
||||
* @package Google\Site_Kit\Modules\Analytics_4
|
||||
* @copyright 2024 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;
|
||||
|
||||
use Google\Site_Kit\Core\Permissions\Permissions;
|
||||
use Google\Site_Kit\Core\Storage\User_Options;
|
||||
use Google\Site_Kit\Modules\Analytics_4;
|
||||
|
||||
/**
|
||||
* The base class for Synchronizing the adsLinked status.
|
||||
*
|
||||
* @since 1.124.0
|
||||
* @access private
|
||||
* @ignore
|
||||
*/
|
||||
class Synchronize_AdsLinked {
|
||||
const CRON_SYNCHRONIZE_ADS_LINKED = 'googlesitekit_cron_synchronize_ads_linked_data';
|
||||
|
||||
/**
|
||||
* Analytics_4 instance.
|
||||
*
|
||||
* @since 1.124.0
|
||||
* @var Analytics_4
|
||||
*/
|
||||
protected $analytics_4;
|
||||
|
||||
/**
|
||||
* User_Options instance.
|
||||
*
|
||||
* @since 1.124.0
|
||||
* @var User_Options
|
||||
*/
|
||||
protected $user_options;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @since 1.124.0
|
||||
*
|
||||
* @param Analytics_4 $analytics_4 Analytics 4 instance.
|
||||
* @param User_Options $user_options User_Options instance.
|
||||
*/
|
||||
public function __construct( Analytics_4 $analytics_4, User_Options $user_options ) {
|
||||
$this->analytics_4 = $analytics_4;
|
||||
$this->user_options = $user_options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers functionality through WordPress hooks.
|
||||
*
|
||||
* @since 1.124.0
|
||||
*/
|
||||
public function register() {
|
||||
add_action(
|
||||
self::CRON_SYNCHRONIZE_ADS_LINKED,
|
||||
function() {
|
||||
$this->synchronize_ads_linked_data();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cron callback for synchronizing the ads linked data.
|
||||
*
|
||||
* @since 1.124.0
|
||||
*/
|
||||
protected function synchronize_ads_linked_data() {
|
||||
$owner_id = $this->analytics_4->get_owner_id();
|
||||
$restore_user = $this->user_options->switch_user( $owner_id );
|
||||
|
||||
if ( user_can( $owner_id, Permissions::VIEW_AUTHENTICATED_DASHBOARD ) ) {
|
||||
$this->synchronize_ads_linked_status();
|
||||
}
|
||||
|
||||
$restore_user();
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronize the adsLinked status.
|
||||
*
|
||||
* @since 1.124.0
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
protected function synchronize_ads_linked_status() {
|
||||
$settings_ga4 = $this->analytics_4->get_settings()->get();
|
||||
$property_id = $settings_ga4['propertyID'];
|
||||
$property_ads_links = $this->analytics_4->get_data(
|
||||
'ads-links',
|
||||
array( 'propertyID' => $property_id )
|
||||
);
|
||||
|
||||
if ( is_wp_error( $property_ads_links ) || ! is_array( $property_ads_links ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Update the adsLinked status and timestamp.
|
||||
$this->analytics_4->get_settings()->merge(
|
||||
array(
|
||||
'adsLinked' => ! empty( $property_ads_links ),
|
||||
'adsLinkedLastSyncedAt' => time(),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules single cron which will synchronize the adsLinked status.
|
||||
*
|
||||
* @since 1.124.0
|
||||
*/
|
||||
public function maybe_schedule_synchronize_ads_linked() {
|
||||
$analytics_4_connected = $this->analytics_4->is_connected();
|
||||
$cron_already_scheduled = wp_next_scheduled( self::CRON_SYNCHRONIZE_ADS_LINKED );
|
||||
|
||||
if ( $analytics_4_connected && ! $cron_already_scheduled ) {
|
||||
wp_schedule_single_event(
|
||||
// Schedule the task to run in 24 hours.
|
||||
time() + ( DAY_IN_SECONDS ),
|
||||
self::CRON_SYNCHRONIZE_ADS_LINKED
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
<?php
|
||||
/**
|
||||
* Class Google\Site_Kit\Modules\Analytics_4\Synchronize_Property
|
||||
*
|
||||
* @package Google\Site_Kit\Modules\Analytics_4
|
||||
* @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;
|
||||
|
||||
use Google\Site_Kit\Core\Permissions\Permissions;
|
||||
use Google\Site_Kit\Core\Storage\User_Options;
|
||||
use Google\Site_Kit\Modules\Analytics_4;
|
||||
use Google\Site_Kit_Dependencies\Google\Service\GoogleAnalyticsAdmin\GoogleAnalyticsAdminV1betaProperty;
|
||||
|
||||
/**
|
||||
* The base class for Synchronizing the Analytics 4 property.
|
||||
*
|
||||
* @since 1.116.0
|
||||
* @access private
|
||||
* @ignore
|
||||
*/
|
||||
class Synchronize_Property {
|
||||
|
||||
const CRON_SYNCHRONIZE_PROPERTY = 'googlesitekit_cron_synchronize_property_data';
|
||||
|
||||
/**
|
||||
* Analytics_4 instance.
|
||||
*
|
||||
* @since 1.116.0
|
||||
* @var Analytics_4
|
||||
*/
|
||||
protected $analytics_4;
|
||||
|
||||
/**
|
||||
* User_Options instance.
|
||||
*
|
||||
* @since 1.116.0
|
||||
* @var User_Options
|
||||
*/
|
||||
protected $user_options;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @since 1.116.0
|
||||
*
|
||||
* @param Analytics_4 $analytics_4 Analytics 4 instance.
|
||||
* @param User_Options $user_options User_Options instance.
|
||||
*/
|
||||
public function __construct( Analytics_4 $analytics_4, User_Options $user_options ) {
|
||||
$this->analytics_4 = $analytics_4;
|
||||
$this->user_options = $user_options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers functionality through WordPress hooks.
|
||||
*
|
||||
* @since 1.116.0
|
||||
*/
|
||||
public function register() {
|
||||
|
||||
add_action(
|
||||
self::CRON_SYNCHRONIZE_PROPERTY,
|
||||
function() {
|
||||
$this->synchronize_property_data();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cron callback for synchronizing the property.
|
||||
*
|
||||
* @since 1.116.0
|
||||
*/
|
||||
protected function synchronize_property_data() {
|
||||
$owner_id = $this->analytics_4->get_owner_id();
|
||||
$restore_user = $this->user_options->switch_user( $owner_id );
|
||||
|
||||
if ( user_can( $owner_id, Permissions::VIEW_AUTHENTICATED_DASHBOARD ) ) {
|
||||
$property = $this->retrieve_property();
|
||||
|
||||
$this->synchronize_property_create_time( $property );
|
||||
}
|
||||
|
||||
$restore_user();
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules single cron which will synchronize the property data.
|
||||
*
|
||||
* @since 1.116.0
|
||||
*/
|
||||
public function maybe_schedule_synchronize_property() {
|
||||
$settings = $this->analytics_4->get_settings()->get();
|
||||
|
||||
$create_time_has_value = (bool) $settings['propertyCreateTime'];
|
||||
$analytics_4_connected = $this->analytics_4->is_connected();
|
||||
$cron_already_scheduled = wp_next_scheduled( self::CRON_SYNCHRONIZE_PROPERTY );
|
||||
|
||||
if ( ! $create_time_has_value && $analytics_4_connected && ! $cron_already_scheduled ) {
|
||||
wp_schedule_single_event(
|
||||
// Schedule the task to run in 30 minutes.
|
||||
time() + ( 30 * MINUTE_IN_SECONDS ),
|
||||
self::CRON_SYNCHRONIZE_PROPERTY
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the Analytics 4 property.
|
||||
*
|
||||
* @since 1.116.0
|
||||
*
|
||||
* @return GoogleAnalyticsAdminV1betaProperty|null $property Analytics 4 property object, or null if property is not found.
|
||||
*/
|
||||
protected function retrieve_property() {
|
||||
$settings = $this->analytics_4->get_settings()->get();
|
||||
|
||||
$property_id = $settings['propertyID'];
|
||||
$property = $this->analytics_4->get_data( 'property', array( 'propertyID' => $property_id ) );
|
||||
|
||||
if ( is_wp_error( $property ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $property;
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronize the property create time data.
|
||||
*
|
||||
* @since 1.116.0
|
||||
*
|
||||
* @param GoogleAnalyticsAdminV1betaProperty|null $property Analytics 4 property object, or null if property is not found.
|
||||
*/
|
||||
protected function synchronize_property_create_time( $property ) {
|
||||
if ( ! $property ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$create_time_ms = self::convert_time_to_unix_ms( $property->createTime ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
|
||||
|
||||
$this->analytics_4->get_settings()->merge(
|
||||
array(
|
||||
'propertyCreateTime' => $create_time_ms,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert to Unix timestamp and then to milliseconds.
|
||||
*
|
||||
* @since 1.116.0
|
||||
*
|
||||
* @param string $date_time Date in date-time format.
|
||||
*/
|
||||
public static function convert_time_to_unix_ms( $date_time ) {
|
||||
$date_time_object = new \DateTime( $date_time, new \DateTimeZone( 'UTC' ) );
|
||||
|
||||
return (int) ( $date_time_object->getTimestamp() * 1000 );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
/**
|
||||
* Class Google\Site_Kit\Modules\Analytics_4\Tag_Guard
|
||||
*
|
||||
* @package Google\Site_Kit\Modules\Analytics_4
|
||||
* @copyright 2021 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;
|
||||
|
||||
use Google\Site_Kit\Core\Modules\Tags\Module_Tag_Guard;
|
||||
|
||||
/**
|
||||
* Class for the Analytics 4 tag guard.
|
||||
*
|
||||
* @since 1.31.0
|
||||
* @access private
|
||||
* @ignore
|
||||
*/
|
||||
class Tag_Guard extends Module_Tag_Guard {
|
||||
|
||||
/**
|
||||
* Determines whether the guarded tag can be activated or not.
|
||||
*
|
||||
* @since 1.31.0
|
||||
*
|
||||
* @return bool|WP_Error TRUE if guarded tag can be activated, otherwise FALSE or an error.
|
||||
*/
|
||||
public function can_activate() {
|
||||
$settings = $this->settings->get();
|
||||
return ! empty( $settings['useSnippet'] ) && ! empty( $settings['measurementID'] );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
/**
|
||||
* Class Google\Site_Kit\Modules\Analytics_4\Tag_Interface
|
||||
*
|
||||
* @package Google\Site_Kit\Modules\Analytics_4
|
||||
* @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;
|
||||
|
||||
/**
|
||||
* Interface for an Analytics 4 tag.
|
||||
*
|
||||
* @since 1.113.0
|
||||
* @access private
|
||||
* @ignore
|
||||
*/
|
||||
interface Tag_Interface {
|
||||
/**
|
||||
* Sets the ads conversion ID.
|
||||
*
|
||||
* @since 1.118.0
|
||||
*
|
||||
* @param string $ads_conversion_id Ads ID.
|
||||
*/
|
||||
public function set_ads_conversion_id( $ads_conversion_id );
|
||||
|
||||
/**
|
||||
* Sets custom dimensions data.
|
||||
*
|
||||
* @since 1.113.0
|
||||
*
|
||||
* @param string $custom_dimensions Custom dimensions data.
|
||||
*/
|
||||
public function set_custom_dimensions( $custom_dimensions );
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
/**
|
||||
* Class Google\Site_Kit\Core\Modules\Analytics_4\Tag_Matchers
|
||||
*
|
||||
* @package Google\Site_Kit\Core\Modules\Analytics_4
|
||||
* @copyright 2024 Google LLC
|
||||
* @license https://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
|
||||
* @link https://sitekit.withgoogle.com
|
||||
*/
|
||||
|
||||
namespace Google\Site_Kit\Core\Modules\Analytics_4;
|
||||
|
||||
use Google\Site_Kit\Core\Modules\Tags\Module_Tag_Matchers;
|
||||
use Google\Site_Kit\Core\Tags\Tag_Matchers_Interface;
|
||||
|
||||
/**
|
||||
* Class for Tag matchers.
|
||||
*
|
||||
* @since 1.119.0
|
||||
* @access private
|
||||
* @ignore
|
||||
*/
|
||||
class Tag_Matchers extends Module_Tag_Matchers implements Tag_Matchers_Interface {
|
||||
|
||||
/**
|
||||
* Holds array of regex tag matchers.
|
||||
*
|
||||
* @since 1.119.0
|
||||
*
|
||||
* @return array Array of regex matchers.
|
||||
*/
|
||||
public function regex_matchers() {
|
||||
$tag_matchers = array(
|
||||
"/__gaTracker\s*\(\s*['|\"]create['|\"]\s*,\s*['|\"](G-[a-zA-Z0-9]+)['|\"]\, ?['|\"]auto['|\"]\s*\)/i",
|
||||
"/_gaq\.push\s*\(\s*\[\s*['|\"][^_]*_setAccount['|\"]\s*,\s*['|\"](G-[a-zA-Z0-9]+)['|\"]\s*],?\s*\)/i",
|
||||
'/<amp-analytics\s+[^>]*type="gtag"[^>]*>[^<]*<script\s+type="application\/json">[^<]*"gtag_id"\s*:\s*"(G-[a-zA-Z0-9]+)"/i',
|
||||
'/<amp-analytics\s+[^>]*type="googleanalytics"[^>]*>[^<]*<script\s+type="application\/json">[^<]*"account"\s*:\s*"(G-[a-zA-Z0-9]+)"/i',
|
||||
);
|
||||
|
||||
$subdomains = array( '', 'www\\.' );
|
||||
foreach ( $subdomains as $subdomain ) {
|
||||
$tag_matchers[] = "/<script\\s+[^>]*src=['|\"]https?:\\/\\/" . $subdomain . "googletagmanager\\.com\\/gtag\\/js\\?id=(G-[a-zA-Z0-9]+)['|\"][^>]*><\\/script>/i";
|
||||
$tag_matchers[] = "/<script\\s+[^>]*src=['|\"]https?:\/\/" . $subdomain . "googletagmanager\\.com\\/gtag\\/js\\?id=(G-[a-zA-Z0-9]+)['|\"][^\\/]*\/>/i";
|
||||
}
|
||||
|
||||
$funcs = array( '__gaTracker', 'ga', 'gtag' );
|
||||
foreach ( $funcs as $func ) {
|
||||
$tag_matchers[] = "/$func\\s*\\(\\s*['|\"]create['|\"]\\s*,\\s*['|\"](G-[a-zA-Z0-9]+)['|\"]\\,\\s*['|\"]auto['|\"]\\s*\\)/i";
|
||||
$tag_matchers[] = "/$func\\s*\\(\\s*['|\"]config['|\"]\\s*,\\s*['|\"](G-[a-zA-Z0-9]+)['|\"]\\s*\\)/i";
|
||||
$tag_matchers[] = "/$func\\s*\\(\\s*['|\"]config['|\"]\\s*,\\s*['|\"](GT-[a-zA-Z0-9]+)['|\"]\\s*\\)/i";
|
||||
}
|
||||
|
||||
return $tag_matchers;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,220 @@
|
||||
<?php
|
||||
/**
|
||||
* Class Google\Site_Kit\Modules\Analytics_4\Web_Tag
|
||||
*
|
||||
* @package Google\Site_Kit\Modules\Analytics_4
|
||||
* @copyright 2021 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;
|
||||
|
||||
use Google\Site_Kit\Core\Modules\Tags\Module_Web_Tag;
|
||||
use Google\Site_Kit\Core\Tags\GTag;
|
||||
use Google\Site_Kit\Core\Tags\Tag_With_DNS_Prefetch_Trait;
|
||||
use Google\Site_Kit\Core\Tags\Tag_With_Linker_Trait;
|
||||
use Google\Site_Kit\Core\Util\Method_Proxy_Trait;
|
||||
use Google\Site_Kit\Core\Tags\Tag_With_Linker_Interface;
|
||||
|
||||
/**
|
||||
* Class for Web tag.
|
||||
*
|
||||
* @since 1.31.0
|
||||
* @access private
|
||||
* @ignore
|
||||
*/
|
||||
class Web_Tag extends Module_Web_Tag implements Tag_Interface, Tag_With_Linker_Interface {
|
||||
|
||||
use Method_Proxy_Trait, Tag_With_DNS_Prefetch_Trait, Tag_With_Linker_Trait;
|
||||
|
||||
/**
|
||||
* Custom dimensions data.
|
||||
*
|
||||
* @since 1.113.0
|
||||
* @var array
|
||||
*/
|
||||
private $custom_dimensions;
|
||||
|
||||
/**
|
||||
* Ads conversion ID.
|
||||
*
|
||||
* @since 1.32.0
|
||||
* @var string
|
||||
*/
|
||||
private $ads_conversion_id;
|
||||
|
||||
/**
|
||||
* Sets custom dimensions data.
|
||||
*
|
||||
* @since 1.113.0
|
||||
*
|
||||
* @param string $custom_dimensions Custom dimensions data.
|
||||
*/
|
||||
public function set_custom_dimensions( $custom_dimensions ) {
|
||||
$this->custom_dimensions = $custom_dimensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current home domain.
|
||||
*
|
||||
* @since 1.24.0
|
||||
*
|
||||
* @param string $domain Domain name.
|
||||
*/
|
||||
public function set_home_domain( $domain ) {
|
||||
$this->home_domain = $domain;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the ads conversion ID.
|
||||
*
|
||||
* @since 1.32.0
|
||||
*
|
||||
* @param string $ads_conversion_id Ads ID.
|
||||
*/
|
||||
public function set_ads_conversion_id( $ads_conversion_id ) {
|
||||
$this->ads_conversion_id = $ads_conversion_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets args to use if blocked_on_consent is deprecated.
|
||||
*
|
||||
* @since 1.122.0
|
||||
*
|
||||
* @return array args to pass to apply_filters_deprecated if deprecated ($version, $replacement, $message)
|
||||
*/
|
||||
protected function get_tag_blocked_on_consent_deprecated_args() {
|
||||
return array(
|
||||
'1.122.0', // Deprecated in this version.
|
||||
'',
|
||||
__( 'Please use the Consent Mode feature instead.', 'google-site-kit' ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers tag hooks.
|
||||
*
|
||||
* @since 1.31.0
|
||||
*/
|
||||
public function register() {
|
||||
add_action( 'googlesitekit_setup_gtag', $this->get_method_proxy( 'setup_gtag' ) );
|
||||
|
||||
$this->do_init_tag_action();
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs gtag snippet.
|
||||
*
|
||||
* @since 1.24.0
|
||||
*/
|
||||
protected function render() {
|
||||
// Do nothing, gtag script is enqueued.
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures gtag script.
|
||||
*
|
||||
* @since 1.24.0
|
||||
* @since 1.124.0 Renamed and refactored to use new GTag infrastructure.
|
||||
*
|
||||
* @param GTag $gtag GTag instance.
|
||||
*/
|
||||
protected function setup_gtag( GTag $gtag ) {
|
||||
$gtag_opt = $this->get_tag_config();
|
||||
|
||||
/**
|
||||
* Filters the gtag configuration options for the Analytics snippet.
|
||||
*
|
||||
* You can use the {@see 'googlesitekit_amp_gtag_opt'} filter to do the same for gtag in AMP.
|
||||
*
|
||||
* @since 1.24.0
|
||||
*
|
||||
* @see https://developers.google.com/gtagjs/devguide/configure
|
||||
*
|
||||
* @param array $gtag_opt gtag config options.
|
||||
*/
|
||||
$gtag_opt = apply_filters( 'googlesitekit_gtag_opt', $gtag_opt );
|
||||
|
||||
if ( ! empty( $gtag_opt['linker'] ) ) {
|
||||
$gtag->add_command( 'set', array( 'linker', $gtag_opt['linker'] ) );
|
||||
|
||||
unset( $gtag_opt['linker'] );
|
||||
}
|
||||
|
||||
$gtag->add_tag( $this->tag_id, $gtag_opt );
|
||||
|
||||
// TODO: Lift this out to the Ads module when it's ready.
|
||||
if ( $this->ads_conversion_id ) {
|
||||
$gtag->add_tag( $this->ads_conversion_id );
|
||||
}
|
||||
|
||||
$filter_google_gtagjs = function ( $tag, $handle ) use ( $gtag ) {
|
||||
if ( GTag::HANDLE !== $handle ) {
|
||||
return $tag;
|
||||
}
|
||||
|
||||
// Retain this comment for detection of Site Kit placed tag.
|
||||
$snippet_comment = sprintf( "\n<!-- %s -->\n", esc_html__( 'Google Analytics snippet added by Site Kit', 'google-site-kit' ) );
|
||||
|
||||
$block_on_consent_attrs = $this->get_tag_blocked_on_consent_attribute();
|
||||
|
||||
if ( $block_on_consent_attrs ) {
|
||||
$gtag_src = $gtag->get_gtag_src();
|
||||
|
||||
$tag = $this->add_legacy_block_on_consent_attributes( $tag, $gtag_src, $block_on_consent_attrs );
|
||||
}
|
||||
|
||||
return $snippet_comment . $tag;
|
||||
};
|
||||
|
||||
add_filter( 'script_loader_tag', $filter_google_gtagjs, 10, 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the tag config as used in the gtag data vars.
|
||||
*
|
||||
* @since 1.113.0
|
||||
*
|
||||
* @return array Tag configuration.
|
||||
*/
|
||||
protected function get_tag_config() {
|
||||
$config = array();
|
||||
|
||||
if ( ! empty( $this->custom_dimensions ) ) {
|
||||
$config = array_merge( $config, $this->custom_dimensions );
|
||||
}
|
||||
|
||||
return $this->add_linker_to_tag_config( $config );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds HTML attributes to the gtag script tag to block it until user consent is granted.
|
||||
*
|
||||
* This mechanism for blocking the tag is deprecated and the Consent Mode feature should be used instead.
|
||||
*
|
||||
* @since 1.122.0
|
||||
*
|
||||
* @param string $tag The script tag.
|
||||
* @param string $gtag_src The gtag script source URL.
|
||||
* @param string $block_on_consent_attrs The attributes to add to the script tag to block it until user consent is granted.
|
||||
* @return string The script tag with the added attributes.
|
||||
*/
|
||||
protected function add_legacy_block_on_consent_attributes( $tag, $gtag_src, $block_on_consent_attrs ) {
|
||||
return str_replace(
|
||||
array(
|
||||
"<script src='$gtag_src'", // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript
|
||||
"<script src=\"$gtag_src\"", // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript
|
||||
"<script type='text/javascript' src='$gtag_src'", // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript
|
||||
"<script type=\"text/javascript\" src=\"$gtag_src\"", // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript
|
||||
),
|
||||
array( // `type` attribute intentionally excluded in replacements.
|
||||
"<script{$block_on_consent_attrs} src='$gtag_src'", // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript
|
||||
"<script{$block_on_consent_attrs} src=\"$gtag_src\"", // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript
|
||||
"<script{$block_on_consent_attrs} src='$gtag_src'", // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript
|
||||
"<script{$block_on_consent_attrs} src=\"$gtag_src\"", // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript
|
||||
),
|
||||
$tag
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user