337 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			337 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
/**
 | 
						|
 *  Google Search Console.
 | 
						|
 *
 | 
						|
 * @since      1.0.49
 | 
						|
 * @package    RankMath
 | 
						|
 * @subpackage RankMath\modules
 | 
						|
 * @author     Rank Math <support@rankmath.com>
 | 
						|
 */
 | 
						|
 | 
						|
namespace RankMath\Google;
 | 
						|
 | 
						|
use RankMath\Helpers\Str;
 | 
						|
use RankMath\Analytics\Workflow\Base;
 | 
						|
use RankMath\Sitemap\Sitemap;
 | 
						|
use WP_Error;
 | 
						|
 | 
						|
defined( 'ABSPATH' ) || exit;
 | 
						|
 | 
						|
/**
 | 
						|
 * Console class.
 | 
						|
 */
 | 
						|
class Console extends Analytics {
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Add site.
 | 
						|
	 *
 | 
						|
	 * @param string $url Site url to add.
 | 
						|
	 *
 | 
						|
	 * @return bool
 | 
						|
	 */
 | 
						|
	public function add_site( $url ) {
 | 
						|
		$this->http_put( 'https://www.googleapis.com/webmasters/v3/sites/' . rawurlencode( $url ) );
 | 
						|
		return $this->is_success();
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Get site verification token.
 | 
						|
	 *
 | 
						|
	 * @param string $url Site url to add.
 | 
						|
	 *
 | 
						|
	 * @return bool|string
 | 
						|
	 */
 | 
						|
	public function get_site_verification_token( $url ) {
 | 
						|
		$args = [
 | 
						|
			'site'               => [
 | 
						|
				'type'       => 'SITE',
 | 
						|
				'identifier' => $url,
 | 
						|
			],
 | 
						|
			'verificationMethod' => 'META',
 | 
						|
		];
 | 
						|
 | 
						|
		$response = $this->http_post( 'https://www.googleapis.com/siteVerification/v1/token', $args );
 | 
						|
		if ( ! $this->is_success() ) {
 | 
						|
			return false;
 | 
						|
		}
 | 
						|
 | 
						|
		return \RankMath\CMB2::sanitize_webmaster_tags( $response['token'] );
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Verify site token.
 | 
						|
	 *
 | 
						|
	 * @param string $url Site url to add.
 | 
						|
	 *
 | 
						|
	 * @return bool|string
 | 
						|
	 */
 | 
						|
	public function verify_site( $url ) {
 | 
						|
		$token = $this->get_site_verification_token( $url );
 | 
						|
		if ( ! $token ) {
 | 
						|
			return;
 | 
						|
		}
 | 
						|
 | 
						|
		// Save in transient.
 | 
						|
		set_transient( 'rank_math_google_site_verification', $token, DAY_IN_SECONDS * 2 );
 | 
						|
 | 
						|
		// Call Google site verification.
 | 
						|
		$args = [
 | 
						|
			'site' => [
 | 
						|
				'type'       => 'SITE',
 | 
						|
				'identifier' => $url,
 | 
						|
			],
 | 
						|
		];
 | 
						|
 | 
						|
		$this->http_post( 'https://www.googleapis.com/siteVerification/v1/webResource?verificationMethod=META', $args );
 | 
						|
 | 
						|
		// Sync sitemap.
 | 
						|
		as_enqueue_async_action( 'rank_math/analytics/sync_sitemaps', [], 'rank-math' );
 | 
						|
 | 
						|
		return $this->is_success();
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Get sites.
 | 
						|
	 *
 | 
						|
	 * @return array
 | 
						|
	 */
 | 
						|
	public function get_sites() {
 | 
						|
		static $rank_math_google_sites;
 | 
						|
		if ( ! \is_null( $rank_math_google_sites ) ) {
 | 
						|
			return $rank_math_google_sites;
 | 
						|
		}
 | 
						|
 | 
						|
		$rank_math_google_sites = [];
 | 
						|
		$response               = $this->http_get( 'https://www.googleapis.com/webmasters/v3/sites' );
 | 
						|
		if ( ! $this->is_success() || empty( $response['siteEntry'] ) ) {
 | 
						|
			return $rank_math_google_sites;
 | 
						|
		}
 | 
						|
 | 
						|
		foreach ( $response['siteEntry'] as $site ) {
 | 
						|
			$rank_math_google_sites[ $site['siteUrl'] ] = $site['siteUrl'];
 | 
						|
		}
 | 
						|
 | 
						|
		return $rank_math_google_sites;
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Fetch sitemaps.
 | 
						|
	 *
 | 
						|
	 * @param string  $url        Site to get sitemaps for.
 | 
						|
	 * @param boolean $with_index With index data.
 | 
						|
	 *
 | 
						|
	 * @return array
 | 
						|
	 */
 | 
						|
	public function get_sitemaps( $url, $with_index = false ) {
 | 
						|
		$with_index = $with_index ? '?sitemapIndex=' . rawurlencode( $url . Sitemap::get_sitemap_index_slug() . '.xml' ) : '';
 | 
						|
		$response   = $this->http_get( 'https://www.googleapis.com/webmasters/v3/sites/' . rawurlencode( $url ) . '/sitemaps' . $with_index );
 | 
						|
 | 
						|
		if ( ! $this->is_success() || empty( $response['sitemap'] ) ) {
 | 
						|
			return [];
 | 
						|
		}
 | 
						|
 | 
						|
		return $response['sitemap'];
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Submit sitemap to search console.
 | 
						|
	 *
 | 
						|
	 * @param string $url     Site to add sitemap for.
 | 
						|
	 * @param string $sitemap Sitemap url.
 | 
						|
	 *
 | 
						|
	 * @return array
 | 
						|
	 */
 | 
						|
	public function add_sitemap( $url, $sitemap ) {
 | 
						|
		return $this->http_put( 'https://www.googleapis.com/webmasters/v3/sites/' . rawurlencode( $url ) . '/sitemaps/' . rawurlencode( $sitemap ) );
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Delete sitemap from search console.
 | 
						|
	 *
 | 
						|
	 * @param string $url     Site to delete sitemap for.
 | 
						|
	 * @param string $sitemap Sitemap url.
 | 
						|
	 *
 | 
						|
	 * @return array
 | 
						|
	 */
 | 
						|
	public function delete_sitemap( $url, $sitemap ) {
 | 
						|
		return $this->http_delete( 'https://www.googleapis.com/webmasters/v3/sites/' . rawurlencode( $url ) . '/sitemaps/' . rawurlencode( $sitemap ) );
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Query analytics data from google client api.
 | 
						|
	 *
 | 
						|
	 * @param array $args  Query arguments.
 | 
						|
	 *
 | 
						|
	 * @return array
 | 
						|
	 */
 | 
						|
	public function get_search_analytics( $args = [] ) {
 | 
						|
		$dates = Base::get_dates();
 | 
						|
 | 
						|
		$start_date = isset( $args['start_date'] ) ? $args['start_date'] : $dates['start_date'];
 | 
						|
		$end_date   = isset( $args['end_date'] ) ? $args['end_date'] : $dates['end_date'];
 | 
						|
		$dimensions = isset( $args['dimensions'] ) ? $args['dimensions'] : 'date';
 | 
						|
		$row_limit  = isset( $args['row_limit'] ) ? $args['row_limit'] : Api::get()->get_row_limit();
 | 
						|
 | 
						|
		$params = [
 | 
						|
			'startDate'  => $start_date,
 | 
						|
			'endDate'    => $end_date,
 | 
						|
			'rowLimit'   => $row_limit,
 | 
						|
			'dimensions' => \is_array( $dimensions ) ? $dimensions : [ $dimensions ],
 | 
						|
		];
 | 
						|
 | 
						|
		$stored  = get_option(
 | 
						|
			'rank_math_google_analytic_profile',
 | 
						|
			[
 | 
						|
				'country'             => '',
 | 
						|
				'profile'             => '',
 | 
						|
				'enable_index_status' => '',
 | 
						|
			]
 | 
						|
		);
 | 
						|
		$country = isset( $args['country'] ) ? $args['country'] : $stored['country'];
 | 
						|
		$profile = isset( $args['profile'] ) ? $args['profile'] : $stored['profile'];
 | 
						|
 | 
						|
		if ( 'all' !== $country ) {
 | 
						|
			$params['dimensionFilterGroups'] = [
 | 
						|
				[
 | 
						|
					'filters' => [
 | 
						|
						[
 | 
						|
							'dimension'  => 'country',
 | 
						|
							'operator'   => 'equals',
 | 
						|
							'expression' => $country,
 | 
						|
						],
 | 
						|
					],
 | 
						|
				],
 | 
						|
			];
 | 
						|
		}
 | 
						|
 | 
						|
		if ( empty( $profile ) ) {
 | 
						|
			$profile = trailingslashit( strtolower( home_url() ) );
 | 
						|
		}
 | 
						|
 | 
						|
		$workflow = 'console';
 | 
						|
		$this->set_workflow( $workflow );
 | 
						|
		$response = $this->http_post(
 | 
						|
			'https://www.googleapis.com/webmasters/v3/sites/' . rawurlencode( $profile ) . '/searchAnalytics/query',
 | 
						|
			$params
 | 
						|
		);
 | 
						|
 | 
						|
		$this->log_failed_request( $response, $workflow, $start_date, func_get_args() );
 | 
						|
 | 
						|
		if ( ! $this->is_success() ) {
 | 
						|
			return new WP_Error( 'request_failed', __( 'The Google Search Console request failed.', 'rank-math' ) );
 | 
						|
		}
 | 
						|
 | 
						|
		if ( ! isset( $response['rows'] ) ) {
 | 
						|
			return false;
 | 
						|
		}
 | 
						|
 | 
						|
		return $response['rows'];
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Is site verified.
 | 
						|
	 *
 | 
						|
	 * @param string $url Site to verify.
 | 
						|
	 *
 | 
						|
	 * @return boolean
 | 
						|
	 */
 | 
						|
	public function is_site_verified( $url ) {
 | 
						|
		$response = $this->http_get( 'https://www.googleapis.com/siteVerification/v1/webResource/' . rawurlencode( $url ) );
 | 
						|
		if ( ! $this->is_success() ) {
 | 
						|
			return false;
 | 
						|
		}
 | 
						|
 | 
						|
		return isset( $response['owners'] );
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Sync sitemaps with google search console.
 | 
						|
	 */
 | 
						|
	public function sync_sitemaps() {
 | 
						|
		$site_url = self::get_site_url();
 | 
						|
		$data     = $this->get_sitemap_to_sync();
 | 
						|
 | 
						|
		// Submit it.
 | 
						|
		if ( ! $data['sitemaps_in_list'] ) {
 | 
						|
			$this->add_sitemap( $site_url, $data['local_sitemap'] );
 | 
						|
		}
 | 
						|
 | 
						|
		if ( empty( $data['delete_sitemaps'] ) ) {
 | 
						|
			return;
 | 
						|
		}
 | 
						|
 | 
						|
		// Delete it.
 | 
						|
		foreach ( $data['delete_sitemaps'] as $sitemap ) {
 | 
						|
			$this->delete_sitemap( $site_url, $sitemap );
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Get sitemaps to sync.
 | 
						|
	 *
 | 
						|
	 * @return array
 | 
						|
	 */
 | 
						|
	private function get_sitemap_to_sync() {
 | 
						|
		$delete_sitemaps  = [];
 | 
						|
		$sitemaps_in_list = false;
 | 
						|
		$site_url         = self::get_site_url();
 | 
						|
		$sitemaps         = $this->get_sitemaps( $site_url );
 | 
						|
		$local_sitemap    = trailingslashit( $site_url ) . Sitemap::get_sitemap_index_slug() . '.xml';
 | 
						|
 | 
						|
		// Early Bail if there are no sitemaps.
 | 
						|
		if ( empty( $sitemaps ) ) {
 | 
						|
			return compact( 'delete_sitemaps', 'sitemaps_in_list', 'local_sitemap' );
 | 
						|
		}
 | 
						|
 | 
						|
		foreach ( $sitemaps as $sitemap ) {
 | 
						|
			if ( $sitemap['path'] === $local_sitemap ) {
 | 
						|
				$sitemaps_in_list = true;
 | 
						|
				continue;
 | 
						|
			}
 | 
						|
 | 
						|
			$delete_sitemaps[] = $sitemap['path'];
 | 
						|
		}
 | 
						|
 | 
						|
		return compact( 'delete_sitemaps', 'sitemaps_in_list', 'local_sitemap' );
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Get site url.
 | 
						|
	 *
 | 
						|
	 * @return string
 | 
						|
	 */
 | 
						|
	public static function get_site_url() {
 | 
						|
		static $rank_math_site_url;
 | 
						|
 | 
						|
		if ( is_null( $rank_math_site_url ) ) {
 | 
						|
			$default            = trailingslashit( strtolower( home_url() ) );
 | 
						|
			$rank_math_site_url = get_option( 'rank_math_google_analytic_profile', [ 'profile' => $default ] );
 | 
						|
			$rank_math_site_url = empty( $rank_math_site_url['profile'] ) ? $default : $rank_math_site_url['profile'];
 | 
						|
 | 
						|
			if ( Str::contains( 'sc-domain:', $rank_math_site_url ) ) {
 | 
						|
				$rank_math_site_url = str_replace( 'sc-domain:', '', $rank_math_site_url );
 | 
						|
				$rank_math_site_url = ( is_ssl() ? 'https://' : 'http://' ) . $rank_math_site_url;
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		return $rank_math_site_url;
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Check if console is connected.
 | 
						|
	 *
 | 
						|
	 * @return boolean Returns True if the console is connected, otherwise False.
 | 
						|
	 */
 | 
						|
	public static function is_console_connected() {
 | 
						|
		$profile = wp_parse_args(
 | 
						|
			get_option( 'rank_math_google_analytic_profile' ),
 | 
						|
			[
 | 
						|
				'profile' => '',
 | 
						|
				'country' => 'all',
 | 
						|
			]
 | 
						|
		);
 | 
						|
 | 
						|
		return ! empty( $profile['profile'] );
 | 
						|
	}
 | 
						|
}
 |