244 lines
6.4 KiB
PHP
244 lines
6.4 KiB
PHP
<?php
|
|
/**
|
|
* Class Google\Site_Kit\Modules\Analytics_4\Audience_Utilities
|
|
*
|
|
* @package Google\Site_Kit\Modules\Analytics_4
|
|
* @copyright 2026 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_Dependencies\Google\Service\GoogleAnalyticsAdminV1alpha\GoogleAnalyticsAdminV1alphaAudience;
|
|
|
|
/**
|
|
* Utility class for manipulating Analytics 4 audiences.
|
|
*
|
|
* @since 1.172.0
|
|
* @access private
|
|
* @ignore
|
|
*/
|
|
class Audience_Utilities {
|
|
|
|
/**
|
|
* Weights for audience types when sorting audiences in the selection panel
|
|
* and within the dashboard widget.
|
|
*/
|
|
const AUDIENCE_TYPE_SORT_ORDER = array(
|
|
'USER_AUDIENCE' => 0,
|
|
'SITE_KIT_AUDIENCE' => 1,
|
|
'DEFAULT_AUDIENCE' => 2,
|
|
);
|
|
|
|
/**
|
|
* Audience_Settings instance.
|
|
*
|
|
* @var Audience_Settings
|
|
*/
|
|
protected $audience_settings;
|
|
|
|
/**
|
|
* Constructor.
|
|
*
|
|
* @since 1.172.0
|
|
*
|
|
* @param Audience_Settings $audience_settings Audience_Settings instance.
|
|
*/
|
|
public function __construct( Audience_Settings $audience_settings ) {
|
|
$this->audience_settings = $audience_settings;
|
|
}
|
|
|
|
/**
|
|
* Sets and returns available audiences.
|
|
*
|
|
* @since 1.172.0
|
|
*
|
|
* @param GoogleAnalyticsAdminV1alphaAudience[] $audiences The audiences to set.
|
|
* @return array The available audiences.
|
|
*/
|
|
public function set_available_audiences( $audiences ) {
|
|
$available_audiences = array_map(
|
|
function ( GoogleAnalyticsAdminV1alphaAudience $audience ) {
|
|
$display_name = $audience->getDisplayName();
|
|
$audience_item = array(
|
|
'name' => $audience->getName(),
|
|
'displayName' => ( 'All Users' === $display_name ) ? 'All visitors' : $display_name,
|
|
'description' => $audience->getDescription(),
|
|
);
|
|
|
|
$audience_slug = $this->get_audience_slug( $audience );
|
|
$audience_type = $this->get_audience_type( $audience_slug );
|
|
|
|
$audience_item['audienceType'] = $audience_type;
|
|
$audience_item['audienceSlug'] = $audience_slug;
|
|
|
|
return $audience_item;
|
|
},
|
|
$audiences
|
|
);
|
|
|
|
usort(
|
|
$available_audiences,
|
|
function ( $audience_a, $audience_b ) use ( $available_audiences ) {
|
|
$audience_index_a = array_search( $audience_a, $available_audiences, true );
|
|
$audience_index_b = array_search( $audience_b, $available_audiences, true );
|
|
|
|
if ( false === $audience_index_a || false === $audience_index_b ) {
|
|
return 0;
|
|
}
|
|
|
|
$audience_a = $available_audiences[ $audience_index_a ];
|
|
$audience_b = $available_audiences[ $audience_index_b ];
|
|
|
|
$audience_type_a = $audience_a['audienceType'];
|
|
$audience_type_b = $audience_b['audienceType'];
|
|
|
|
if ( $audience_type_a === $audience_type_b ) {
|
|
if ( 'SITE_KIT_AUDIENCE' === $audience_type_b ) {
|
|
return 'new-visitors' === $audience_a['audienceSlug'] ? -1 : 1;
|
|
}
|
|
|
|
return $audience_index_a - $audience_index_b;
|
|
}
|
|
|
|
$weight_a = self::AUDIENCE_TYPE_SORT_ORDER[ $audience_type_a ];
|
|
$weight_b = self::AUDIENCE_TYPE_SORT_ORDER[ $audience_type_b ];
|
|
|
|
if ( $weight_a === $weight_b ) {
|
|
return $audience_index_a - $audience_index_b;
|
|
}
|
|
|
|
return $weight_a - $weight_b;
|
|
}
|
|
);
|
|
|
|
$this->audience_settings->merge(
|
|
array(
|
|
'availableAudiences' => $available_audiences,
|
|
'availableAudiencesLastSyncedAt' => time(),
|
|
)
|
|
);
|
|
|
|
return $available_audiences;
|
|
}
|
|
|
|
/**
|
|
* Returns the Site Kit-created audience display names from the passed list of audiences.
|
|
*
|
|
* @since 1.172.0
|
|
*
|
|
* @param array $audiences List of audiences.
|
|
*
|
|
* @return array List of Site Kit-created audience display names.
|
|
*/
|
|
public function get_site_kit_audiences( $audiences ) {
|
|
// Ensure that audiences are available, otherwise return an empty array.
|
|
if ( empty( $audiences ) || ! is_array( $audiences ) ) {
|
|
return array();
|
|
}
|
|
|
|
$site_kit_audiences = array_filter( $audiences, fn ( $audience ) => ! empty( $audience['audienceType'] ) && ( 'SITE_KIT_AUDIENCE' === $audience['audienceType'] ) );
|
|
|
|
if ( empty( $site_kit_audiences ) ) {
|
|
return array();
|
|
}
|
|
|
|
return wp_list_pluck( $site_kit_audiences, 'displayName' );
|
|
}
|
|
|
|
/**
|
|
* Gets the audience slug.
|
|
*
|
|
* @since 1.172.0
|
|
*
|
|
* @param GoogleAnalyticsAdminV1alphaAudience $audience The audience object.
|
|
* @return string The audience slug.
|
|
*/
|
|
private function get_audience_slug( GoogleAnalyticsAdminV1alphaAudience $audience ) {
|
|
$display_name = $audience->getDisplayName();
|
|
|
|
if ( 'All Users' === $display_name ) {
|
|
return 'all-users';
|
|
}
|
|
|
|
if ( 'Purchasers' === $display_name ) {
|
|
return 'purchasers';
|
|
}
|
|
|
|
$filter_clauses = $audience->getFilterClauses();
|
|
|
|
if ( $filter_clauses ) {
|
|
if ( $this->has_audience_site_kit_identifier(
|
|
$filter_clauses,
|
|
'new_visitors'
|
|
) ) {
|
|
return 'new-visitors';
|
|
}
|
|
|
|
if ( $this->has_audience_site_kit_identifier(
|
|
$filter_clauses,
|
|
'returning_visitors'
|
|
) ) {
|
|
return 'returning-visitors';
|
|
}
|
|
}
|
|
|
|
// Return an empty string for user defined audiences.
|
|
return '';
|
|
}
|
|
|
|
/**
|
|
* Gets the audience type based on the audience slug.
|
|
*
|
|
* @since 1.172.0
|
|
*
|
|
* @param string $audience_slug The audience slug.
|
|
* @return string The audience type.
|
|
*/
|
|
private function get_audience_type( $audience_slug ) {
|
|
switch ( $audience_slug ) {
|
|
case 'all-users':
|
|
case 'purchasers':
|
|
return 'DEFAULT_AUDIENCE';
|
|
case 'new-visitors':
|
|
case 'returning-visitors':
|
|
return 'SITE_KIT_AUDIENCE';
|
|
}
|
|
|
|
return 'USER_AUDIENCE';
|
|
}
|
|
|
|
/**
|
|
* Checks if an audience Site Kit identifier
|
|
* (e.g. `created_by_googlesitekit:new_visitors`) exists in a nested array or object.
|
|
*
|
|
* @since 1.172.0
|
|
*
|
|
* @param array|object $data The array or object to search.
|
|
* @param mixed $identifier The identifier to search for.
|
|
* @return bool True if the value exists, false otherwise.
|
|
*/
|
|
private function has_audience_site_kit_identifier( $data, $identifier ) {
|
|
if ( is_array( $data ) || is_object( $data ) ) {
|
|
foreach ( $data as $key => $value ) {
|
|
if ( is_array( $value ) || is_object( $value ) ) {
|
|
// Recursively search the nested structure.
|
|
if ( $this->has_audience_site_kit_identifier( $value, $identifier ) ) {
|
|
return true;
|
|
}
|
|
} elseif (
|
|
'fieldName' === $key &&
|
|
'groupId' === $value &&
|
|
isset( $data['stringFilter'] ) &&
|
|
"created_by_googlesitekit:{$identifier}" === $data['stringFilter']['value']
|
|
) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|