You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
574 lines
17 KiB
PHTML
574 lines
17 KiB
PHTML
7 months ago
|
<?php
|
||
|
/**
|
||
|
* The Analytics AJAX
|
||
|
*
|
||
|
* @since 1.0.49
|
||
|
* @package RankMath
|
||
|
* @subpackage RankMath\modules
|
||
|
* @author Rank Math <support@rankmath.com>
|
||
|
*/
|
||
|
|
||
|
namespace RankMath\Analytics;
|
||
|
|
||
|
use RankMath\Helper;
|
||
|
use RankMath\Google\Api;
|
||
|
use RankMath\Helpers\Str;
|
||
|
use RankMath\Helpers\Param;
|
||
|
use RankMath\Google\Analytics;
|
||
|
use RankMath\Google\Authentication;
|
||
|
use RankMath\Sitemap\Sitemap;
|
||
|
use RankMath\Google\Console as Google_Analytics;
|
||
|
|
||
|
defined( 'ABSPATH' ) || exit;
|
||
|
|
||
|
/**
|
||
|
* AJAX class.
|
||
|
*/
|
||
|
class AJAX {
|
||
|
|
||
|
use \RankMath\Traits\Ajax;
|
||
|
|
||
|
/**
|
||
|
* The Constructor
|
||
|
*/
|
||
|
public function __construct() {
|
||
|
$this->ajax( 'query_analytics', 'query_analytics' );
|
||
|
$this->ajax( 'add_site_console', 'add_site_console' );
|
||
|
$this->ajax( 'disconnect_google', 'disconnect_google' );
|
||
|
$this->ajax( 'verify_site_console', 'verify_site_console' );
|
||
|
$this->ajax( 'google_check_all_services', 'check_all_services' );
|
||
|
|
||
|
// Google Data Management Services.
|
||
|
$this->ajax( 'analytics_delete_cache', 'delete_cache' );
|
||
|
$this->ajax( 'analytic_start_fetching', 'analytic_start_fetching' );
|
||
|
$this->ajax( 'analytic_cancel_fetching', 'analytic_cancel_fetching' );
|
||
|
|
||
|
// Save Linked Google Account info Services.
|
||
|
$this->ajax( 'check_console_request', 'check_console_request' );
|
||
|
$this->ajax( 'check_analytics_request', 'check_analytics_request' );
|
||
|
$this->ajax( 'save_analytic_profile', 'save_analytic_profile' );
|
||
|
$this->ajax( 'save_analytic_options', 'save_analytic_options' );
|
||
|
|
||
|
// Create new GA4 property.
|
||
|
$this->ajax( 'create_ga4_property', 'create_ga4_property' );
|
||
|
$this->ajax( 'get_ga4_data_streams', 'get_ga4_data_streams' );
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Create a new GA4 property.
|
||
|
*/
|
||
|
public function create_ga4_property() {
|
||
|
check_ajax_referer( 'rank-math-ajax-nonce', 'security' );
|
||
|
$this->has_cap_ajax( 'analytics' );
|
||
|
$account_id = Param::post( 'accountID', false, FILTER_SANITIZE_SPECIAL_CHARS, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH | FILTER_FLAG_STRIP_BACKTICK );
|
||
|
|
||
|
$timezone = get_option( 'timezone_string' );
|
||
|
$offset = get_option( 'gmt_offset' );
|
||
|
|
||
|
if ( empty( $timezone ) && 0 !== $offset && floor( $offset ) === $offset ) {
|
||
|
$offset_st = $offset > 0 ? "-$offset" : '+' . absint( $offset );
|
||
|
$timezone = 'Etc/GMT' . $offset_st;
|
||
|
}
|
||
|
|
||
|
$args = [
|
||
|
'displayName' => get_bloginfo( 'sitename' ) . ' - GA4',
|
||
|
'parent' => "accounts/{$account_id}",
|
||
|
'timeZone' => empty( $timezone ) ? 'UTC' : $timezone,
|
||
|
];
|
||
|
|
||
|
$response = Api::get()->http_post(
|
||
|
'https://analyticsadmin.googleapis.com/v1alpha/properties',
|
||
|
$args
|
||
|
);
|
||
|
|
||
|
if ( ! empty( $response['error'] ) ) {
|
||
|
$this->error( $response['error']['message'] );
|
||
|
}
|
||
|
|
||
|
$property_id = str_replace( 'properties/', '', $response['name'] );
|
||
|
$property_name = esc_html( $response['displayName'] );
|
||
|
$all_accounts = get_option( 'rank_math_analytics_all_services' );
|
||
|
if ( isset( $all_accounts['accounts'][ $account_id ] ) ) {
|
||
|
$all_accounts['accounts'][ $account_id ]['properties'][ $property_id ] = [
|
||
|
'name' => $property_name,
|
||
|
'id' => $property_id,
|
||
|
'account_id' => $account_id,
|
||
|
'type' => 'GA4',
|
||
|
];
|
||
|
|
||
|
update_option( 'rank_math_analytics_all_services', $all_accounts );
|
||
|
}
|
||
|
|
||
|
$this->success(
|
||
|
[
|
||
|
'id' => $property_id,
|
||
|
'name' => $property_name,
|
||
|
]
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get the list of Web data streams.
|
||
|
*/
|
||
|
public function get_ga4_data_streams() {
|
||
|
check_ajax_referer( 'rank-math-ajax-nonce', 'security' );
|
||
|
$this->has_cap_ajax( 'analytics' );
|
||
|
$property_id = Param::post( 'propertyID', false, FILTER_SANITIZE_SPECIAL_CHARS, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH | FILTER_FLAG_STRIP_BACKTICK );
|
||
|
|
||
|
$response = Api::get()->http_get(
|
||
|
"https://analyticsadmin.googleapis.com/v1alpha/properties/{$property_id}/dataStreams"
|
||
|
);
|
||
|
|
||
|
if ( ! empty( $response['error'] ) ) {
|
||
|
$this->error( $response['error']['message'] );
|
||
|
}
|
||
|
|
||
|
if ( ! empty( $response['dataStreams'] ) ) {
|
||
|
$streams = [];
|
||
|
foreach ( $response['dataStreams'] as $data_stream ) {
|
||
|
$streams[] = [
|
||
|
'id' => str_replace( "properties/{$property_id}/dataStreams/", '', $data_stream['name'] ),
|
||
|
'name' => $data_stream['displayName'],
|
||
|
'measurementId' => $data_stream['webStreamData']['measurementId'],
|
||
|
];
|
||
|
}
|
||
|
|
||
|
$this->success( [ 'streams' => $streams ] );
|
||
|
}
|
||
|
|
||
|
$stream = $this->create_ga4_data_stream( "properties/{$property_id}" );
|
||
|
if ( ! is_array( $stream ) ) {
|
||
|
$this->error( $stream );
|
||
|
}
|
||
|
|
||
|
$this->success( [ 'streams' => [ $stream ] ] );
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Check the Google Search Console request.
|
||
|
*/
|
||
|
public function check_console_request() {
|
||
|
check_ajax_referer( 'rank-math-ajax-nonce', 'security' );
|
||
|
$this->has_cap_ajax( 'analytics' );
|
||
|
|
||
|
$success = Api::get()->get_search_analytics();
|
||
|
|
||
|
if ( is_wp_error( $success ) ) {
|
||
|
$this->error( esc_html__( 'Data import will not work for this service as sufficient permissions are not given.', 'rank-math' ) );
|
||
|
}
|
||
|
|
||
|
$this->success();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Check the Google Analytics request.
|
||
|
*/
|
||
|
public function check_analytics_request() {
|
||
|
check_ajax_referer( 'rank-math-ajax-nonce', 'security' );
|
||
|
$this->has_cap_ajax( 'analytics' );
|
||
|
|
||
|
$success = Analytics::get_analytics( [], true );
|
||
|
|
||
|
if ( is_wp_error( $success ) ) {
|
||
|
$this->error( esc_html__( 'Data import will not work for this service as sufficient permissions are not given.', 'rank-math' ) );
|
||
|
}
|
||
|
|
||
|
$this->success();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Save analytic profile.
|
||
|
*/
|
||
|
public function save_analytic_profile() {
|
||
|
check_ajax_referer( 'rank-math-ajax-nonce', 'security' );
|
||
|
$this->has_cap_ajax( 'analytics' );
|
||
|
|
||
|
$profile = Param::post( 'profile' );
|
||
|
$country = Param::post( 'country', 'all' );
|
||
|
$days = Param::get( 'days', 90, FILTER_VALIDATE_INT );
|
||
|
$enable_index_status = Param::post( 'enableIndexStatus', false, FILTER_VALIDATE_BOOLEAN );
|
||
|
|
||
|
$success = Api::get()->get_search_analytics(
|
||
|
[
|
||
|
'country' => $country,
|
||
|
'profile' => $profile,
|
||
|
]
|
||
|
);
|
||
|
|
||
|
if ( is_wp_error( $success ) ) {
|
||
|
$this->error( esc_html__( 'Data import will not work for this service as sufficient permissions are not given.', 'rank-math' ) );
|
||
|
}
|
||
|
|
||
|
$prev = get_option( 'rank_math_google_analytic_profile', [] );
|
||
|
$value = [
|
||
|
'country' => $country,
|
||
|
'profile' => $profile,
|
||
|
'enable_index_status' => $enable_index_status,
|
||
|
];
|
||
|
update_option( 'rank_math_google_analytic_profile', $value );
|
||
|
|
||
|
// Remove other stored sites from option for privacy.
|
||
|
$all_accounts = get_option( 'rank_math_analytics_all_services', [] );
|
||
|
$all_accounts['sites'] = [ $profile => $profile ];
|
||
|
|
||
|
update_option( 'rank_math_analytics_all_services', $all_accounts );
|
||
|
|
||
|
// Purge Cache.
|
||
|
if ( ! empty( array_diff( $prev, $value ) ) ) {
|
||
|
DB::purge_cache();
|
||
|
}
|
||
|
|
||
|
// Start fetching console data.
|
||
|
Workflow\Workflow::do_workflow(
|
||
|
'console',
|
||
|
$days,
|
||
|
$prev,
|
||
|
$value
|
||
|
);
|
||
|
|
||
|
$this->success();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Save analytic profile.
|
||
|
*/
|
||
|
public function save_analytic_options() {
|
||
|
check_ajax_referer( 'rank-math-ajax-nonce', 'security' );
|
||
|
$this->has_cap_ajax( 'analytics' );
|
||
|
|
||
|
$value = [
|
||
|
'account_id' => Param::post( 'accountID', false, FILTER_SANITIZE_SPECIAL_CHARS, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH | FILTER_FLAG_STRIP_BACKTICK ),
|
||
|
'property_id' => Param::post( 'propertyID', false, FILTER_SANITIZE_SPECIAL_CHARS, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH | FILTER_FLAG_STRIP_BACKTICK ),
|
||
|
'view_id' => Param::post( 'viewID', false, FILTER_SANITIZE_SPECIAL_CHARS, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH | FILTER_FLAG_STRIP_BACKTICK ),
|
||
|
'measurement_id' => Param::post( 'measurementID', false, FILTER_SANITIZE_SPECIAL_CHARS, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH | FILTER_FLAG_STRIP_BACKTICK ),
|
||
|
'stream_name' => Param::post( 'streamName', false, FILTER_SANITIZE_SPECIAL_CHARS, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH | FILTER_FLAG_STRIP_BACKTICK ),
|
||
|
'country' => Param::post( 'country', 'all', FILTER_SANITIZE_SPECIAL_CHARS, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_BACKTICK ),
|
||
|
'install_code' => Param::post( 'installCode', false, FILTER_VALIDATE_BOOLEAN ),
|
||
|
'anonymize_ip' => Param::post( 'anonymizeIP', false, FILTER_VALIDATE_BOOLEAN ),
|
||
|
'local_ga_js' => Param::post( 'localGAJS', false, FILTER_VALIDATE_BOOLEAN ),
|
||
|
'exclude_loggedin' => Param::post( 'excludeLoggedin', false, FILTER_VALIDATE_BOOLEAN ),
|
||
|
];
|
||
|
|
||
|
// Test Google Analytics (GA) connection request.
|
||
|
if ( ! empty( $value['view_id'] ) || ! empty( $value['country'] ) || ! empty( $value['property_id'] ) ) {
|
||
|
$request = Analytics::get_analytics(
|
||
|
[
|
||
|
'view_id' => $value['view_id'],
|
||
|
'country' => $value['country'],
|
||
|
'property_id' => $value['property_id'],
|
||
|
],
|
||
|
true
|
||
|
);
|
||
|
|
||
|
if ( is_wp_error( $request ) ) {
|
||
|
$this->error( esc_html__( 'Data import will not work for this service as sufficient permissions are not given.', 'rank-math' ) );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$days = Param::get( 'days', 90, FILTER_VALIDATE_INT );
|
||
|
|
||
|
$prev = get_option( 'rank_math_google_analytic_options' );
|
||
|
// Preserve adsense info.
|
||
|
if ( isset( $prev['adsense_id'] ) ) {
|
||
|
$value['adsense_id'] = $prev['adsense_id'];
|
||
|
}
|
||
|
update_option( 'rank_math_google_analytic_options', $value );
|
||
|
|
||
|
// Remove other stored accounts from option for privacy.
|
||
|
$all_accounts = get_option( 'rank_math_analytics_all_services', [] );
|
||
|
if ( isset( $all_accounts['accounts'][ $value['account_id'] ] ) ) {
|
||
|
$account = $all_accounts['accounts'][ $value['account_id'] ];
|
||
|
|
||
|
if ( isset( $account['properties'][ $value['property_id'] ] ) ) {
|
||
|
$property = $account['properties'][ $value['property_id'] ];
|
||
|
$account['properties'] = [ $value['property_id'] => $property ];
|
||
|
}
|
||
|
|
||
|
$all_accounts['accounts'] = [ $value['account_id'] => $account ];
|
||
|
}
|
||
|
update_option( 'rank_math_analytics_all_services', $all_accounts );
|
||
|
|
||
|
// Start fetching analytics data.
|
||
|
Workflow\Workflow::do_workflow(
|
||
|
'analytics',
|
||
|
$days,
|
||
|
$prev,
|
||
|
$value
|
||
|
);
|
||
|
|
||
|
$this->success();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Disconnect google.
|
||
|
*/
|
||
|
public function disconnect_google() {
|
||
|
check_ajax_referer( 'rank-math-ajax-nonce', 'security' );
|
||
|
$this->has_cap_ajax( 'analytics' );
|
||
|
Api::get()->revoke_token();
|
||
|
Workflow\Workflow::kill_workflows();
|
||
|
|
||
|
$this->success();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Cancel fetching data.
|
||
|
*/
|
||
|
public function analytic_cancel_fetching() {
|
||
|
check_ajax_referer( 'rank-math-ajax-nonce', 'security' );
|
||
|
$this->has_cap_ajax( 'analytics' );
|
||
|
Workflow\Workflow::kill_workflows();
|
||
|
|
||
|
$this->success( esc_html__( 'Data fetching cancelled.', 'rank-math' ) );
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Start data fetching for console, analytics, adsense.
|
||
|
*/
|
||
|
public function analytic_start_fetching() {
|
||
|
check_ajax_referer( 'rank-math-ajax-nonce', 'security' );
|
||
|
$this->has_cap_ajax( 'analytics' );
|
||
|
|
||
|
if ( ! Authentication::is_authorized() ) {
|
||
|
$this->error( esc_html__( 'Google oAuth is not authorized.', 'rank-math' ) );
|
||
|
}
|
||
|
|
||
|
$days = Param::get( 'days', 90, FILTER_VALIDATE_INT );
|
||
|
$days = $days * 2;
|
||
|
$rows = DB::objects()
|
||
|
->selectCount( 'id' )
|
||
|
->getVar();
|
||
|
|
||
|
if ( empty( $rows ) ) {
|
||
|
delete_option( 'rank_math_analytics_installed' );
|
||
|
}
|
||
|
delete_option( 'rank_math_analytics_last_single_action_schedule_time' );
|
||
|
// Start fetching data.
|
||
|
foreach ( [ 'console', 'analytics', 'adsense' ] as $action ) {
|
||
|
Workflow\Workflow::do_workflow(
|
||
|
$action,
|
||
|
$days,
|
||
|
null,
|
||
|
null
|
||
|
);
|
||
|
}
|
||
|
|
||
|
$this->success( esc_html__( 'Data fetching started in the background.', 'rank-math' ) );
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Delete cache.
|
||
|
*/
|
||
|
public function delete_cache() {
|
||
|
check_ajax_referer( 'rank-math-ajax-nonce', 'security' );
|
||
|
$this->has_cap_ajax( 'analytics' );
|
||
|
|
||
|
$days = Param::get( 'days', false, FILTER_VALIDATE_INT );
|
||
|
if ( ! $days ) {
|
||
|
$this->error( esc_html__( 'Not a valid settings founds to delete cache.', 'rank-math' ) );
|
||
|
}
|
||
|
|
||
|
// Delete fetched console data within specified date range.
|
||
|
DB::delete_by_days( $days );
|
||
|
|
||
|
// Cancel data fetch action.
|
||
|
Workflow\Workflow::kill_workflows();
|
||
|
delete_transient( 'rank_math_analytics_data_info' );
|
||
|
$db_info = DB::info();
|
||
|
$db_info['message'] = sprintf( '<div class="rank-math-console-db-info"><span class="dashicons dashicons-calendar-alt"></span> Cached Days: <strong>%s</strong></div>', $db_info['days'] ) .
|
||
|
sprintf( '<div class="rank-math-console-db-info"><span class="dashicons dashicons-editor-ul"></span> Data Rows: <strong>%s</strong></div>', Str::human_number( $db_info['rows'] ) ) .
|
||
|
sprintf( '<div class="rank-math-console-db-info"><span class="dashicons dashicons-editor-code"></span> Size: <strong>%s</strong></div>', size_format( $db_info['size'] ) );
|
||
|
|
||
|
$this->success( $db_info );
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Search objects info by title or page and return.
|
||
|
*/
|
||
|
public function query_analytics() {
|
||
|
check_ajax_referer( 'rank-math-ajax-nonce', 'security' );
|
||
|
$this->has_cap_ajax( 'analytics' );
|
||
|
|
||
|
$query = Param::get( 'query', '', FILTER_SANITIZE_SPECIAL_CHARS, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_BACKTICK );
|
||
|
|
||
|
$data = DB::objects()
|
||
|
->whereLike( 'title', $query )
|
||
|
->orWhereLike( 'page', $query )
|
||
|
->limit( 10 )
|
||
|
->get();
|
||
|
|
||
|
$this->send( [ 'data' => $data ] );
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Check all google services.
|
||
|
*/
|
||
|
public function check_all_services() {
|
||
|
check_ajax_referer( 'rank-math-ajax-nonce', 'security' );
|
||
|
$this->has_cap_ajax( 'analytics' );
|
||
|
|
||
|
$result = [
|
||
|
'isVerified' => false,
|
||
|
'inSearchConsole' => false,
|
||
|
'hasSitemap' => false,
|
||
|
'hasAnalytics' => false,
|
||
|
'hasAnalyticsProperty' => false,
|
||
|
];
|
||
|
|
||
|
$result['homeUrl'] = Google_Analytics::get_site_url();
|
||
|
$result['sites'] = Api::get()->get_sites();
|
||
|
$result['inSearchConsole'] = $this->is_site_in_search_console();
|
||
|
|
||
|
if ( $result['inSearchConsole'] ) {
|
||
|
$result['isVerified'] = Helper::is_localhost() ? true : Api::get()->is_site_verified( Google_Analytics::get_site_url() );
|
||
|
$result['hasSitemap'] = $this->has_sitemap_submitted();
|
||
|
}
|
||
|
|
||
|
$result['accounts'] = Api::get()->get_analytics_accounts();
|
||
|
|
||
|
if ( ! empty( $result['accounts'] ) ) {
|
||
|
$result['hasAnalytics'] = true;
|
||
|
$result['hasAnalyticsProperty'] = $this->is_site_in_analytics( $result['accounts'] );
|
||
|
}
|
||
|
|
||
|
$result = apply_filters( 'rank_math/analytics/check_all_services', $result );
|
||
|
|
||
|
update_option( 'rank_math_analytics_all_services', $result );
|
||
|
|
||
|
$this->success( $result );
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Add site to search console
|
||
|
*/
|
||
|
public function add_site_console() {
|
||
|
check_ajax_referer( 'rank-math-ajax-nonce', 'security' );
|
||
|
$this->has_cap_ajax( 'analytics' );
|
||
|
|
||
|
$home_url = Google_Analytics::get_site_url();
|
||
|
Api::get()->add_site( $home_url );
|
||
|
Api::get()->verify_site( $home_url );
|
||
|
|
||
|
$this->success( [ 'sites' => Api::get()->get_sites() ] );
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Verify site console.
|
||
|
*/
|
||
|
public function verify_site_console() {
|
||
|
check_ajax_referer( 'rank-math-ajax-nonce', 'security' );
|
||
|
$this->has_cap_ajax( 'analytics' );
|
||
|
|
||
|
$home_url = Google_Analytics::get_site_url();
|
||
|
Api::get()->verify_site( $home_url );
|
||
|
|
||
|
$this->success( [ 'verified' => true ] );
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Is site in search console.
|
||
|
*
|
||
|
* @return boolean
|
||
|
*/
|
||
|
private function is_site_in_search_console() {
|
||
|
// Early Bail!!
|
||
|
if ( Helper::is_localhost() ) {
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
$sites = Api::get()->get_sites();
|
||
|
$home_url = Google_Analytics::get_site_url();
|
||
|
|
||
|
foreach ( $sites as $site ) {
|
||
|
if ( trailingslashit( $site ) === $home_url ) {
|
||
|
$profile = get_option( 'rank_math_google_analytic_profile' );
|
||
|
if ( empty( $profile ) ) {
|
||
|
update_option(
|
||
|
'rank_math_google_analytic_profile',
|
||
|
[
|
||
|
'country' => 'all',
|
||
|
'profile' => $home_url,
|
||
|
]
|
||
|
);
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Is site in analytics.
|
||
|
*
|
||
|
* @param array $accounts Analytics accounts.
|
||
|
*
|
||
|
* @return boolean
|
||
|
*/
|
||
|
private function is_site_in_analytics( $accounts ) {
|
||
|
$home_url = Google_Analytics::get_site_url();
|
||
|
|
||
|
foreach ( $accounts as $account ) {
|
||
|
foreach ( $account['properties'] as $property ) {
|
||
|
if ( ! empty( $property['url'] ) && trailingslashit( $property['url'] ) === $home_url ) {
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Has sitemap in search console.
|
||
|
*
|
||
|
* @return boolean
|
||
|
*/
|
||
|
private function has_sitemap_submitted() {
|
||
|
$home_url = Google_Analytics::get_site_url();
|
||
|
$sitemaps = Api::get()->get_sitemaps( $home_url );
|
||
|
|
||
|
if ( ! \is_array( $sitemaps ) || empty( $sitemaps ) ) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
foreach ( $sitemaps as $sitemap ) {
|
||
|
if ( $sitemap['path'] === $home_url . Sitemap::get_sitemap_index_slug() . '.xml' ) {
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Create a new data stream.
|
||
|
*
|
||
|
* @param string $property_id GA4 property ID.
|
||
|
*/
|
||
|
private function create_ga4_data_stream( $property_id ) {
|
||
|
$args = [
|
||
|
'type' => 'WEB_DATA_STREAM',
|
||
|
'displayName' => 'Website',
|
||
|
'webStreamData' => [
|
||
|
'defaultUri' => home_url(),
|
||
|
],
|
||
|
];
|
||
|
|
||
|
$stream = Api::get()->http_post(
|
||
|
"https://analyticsadmin.googleapis.com/v1alpha/{$property_id}/dataStreams",
|
||
|
$args
|
||
|
);
|
||
|
|
||
|
if ( ! empty( $stream['error'] ) ) {
|
||
|
return $stream['error']['message'];
|
||
|
}
|
||
|
|
||
|
return [
|
||
|
'id' => str_replace( "properties/{$property_id}/dataStreams/", '', $stream['name'] ),
|
||
|
'name' => $stream['displayName'],
|
||
|
'measurementId' => $stream['webStreamData']['measurementId'],
|
||
|
];
|
||
|
}
|
||
|
}
|