File "site-verification.php"
Full Path: /home/fresvfqn/waterdamagerestorationandrepairsmithtown.com/wp-content/plugins/surerank/inc/google-search-console/site-verification.php
File size: 10.54 KB
MIME-type: text/x-php
Charset: utf-8
<?php
/**
* Site Verification Class
*
* Handles Google Site Verification API operations.
*
* @since 1.4.0
* @package SureRank
*/
namespace SureRank\Inc\GoogleSearchConsole;
use SureRank\Inc\Traits\Get_Instance;
/**
* Site Verification Class
*
* Responsible for handling Google Site Verification API operations.
*
* @since 1.4.0
*/
class SiteVerification {
use Get_Instance;
/**
* Google Site Verification API Base
*/
private const GOOGLE_SITE_VERIFICATION_API_BASE = 'https://www.googleapis.com/siteVerification/v1/';
/**
* Verification Token Option Name
*/
private const VERIFICATION_TOKEN_OPTION = 'surerank_gsc_verification_token';
/**
* Constructor
*
* @since 1.4.0
* @return void
*/
public function __construct() {
}
/**
* Call Site Verification API
*
* Makes API calls using GoogleConsole call_api method with site verification specific error handling
*
* @since 1.4.0
* @param string $endpoint The API endpoint URL.
* @param string $method HTTP method (GET, POST, PUT, etc.).
* @param array<string, mixed> $args Request arguments.
* @return array<string, mixed> API response or error array.
*/
public function call_site_verification_api( $endpoint, $method = 'GET', $args = [] ) {
$result = GoogleConsole::get_instance()->call_api( $endpoint, $method, $args );
if ( isset( $result['error'] ) && $result['error'] ) {
$original_error_message = $result['message'] ?? __( 'Unknown error', 'surerank' );
$response_code = $result['code'] ?? 0;
$custom_error_message = $original_error_message;
switch ( $response_code ) {
case 400:
if ( strpos( $original_error_message, 'already verified' ) !== false ) {
$custom_error_message = __( 'This site is already verified with Google.', 'surerank' );
} elseif ( strpos( $original_error_message, 'invalid' ) !== false ) {
$custom_error_message = __( 'Invalid site URL format for verification. Please check the URL.', 'surerank' );
}
break;
case 401:
$custom_error_message = __( 'Authentication expired. Please disconnect and reconnect your Google account.', 'surerank' );
break;
case 403:
$custom_error_message = __( 'Access denied. Please disconnect and reconnect your Google account with the necessary permissions.', 'surerank' );
break;
case 404:
$custom_error_message = __( 'Verification resource not found. Please try again.', 'surerank' );
break;
case 409:
$custom_error_message = __( 'Site verification conflict. This site may already be verified by another user.', 'surerank' );
break;
case 429:
$custom_error_message = __( 'Too many verification requests. Please wait a moment and try again.', 'surerank' );
break;
case 500:
case 502:
case 503:
$custom_error_message = __( 'Google Site Verification service is temporarily unavailable. Please try again later.', 'surerank' );
break;
default:
if ( empty( $original_error_message ) || $original_error_message === 'Unknown error' ) {
$custom_error_message = sprintf(
/* translators: %d: HTTP status code */
__( 'Site verification error (Code: %d). Please try again.', 'surerank' ),
$response_code
);
}
break;
}
return [
'error' => true,
'message' => $custom_error_message,
'original_message' => $original_error_message,
'code' => $result['code'] ?? 0,
'http_code' => $response_code,
];
}
return $result;
}
/**
* Get Verification Token
*
* Gets the HTML tag verification token for a site using Site Verification API
*
* @since 1.4.0
* @param string $site_url The site URL to get verification token for.
* @return array<string, mixed>|array<int, array<string, mixed>>
*/
public function get_verification_token( $site_url ) {
$url = self::GOOGLE_SITE_VERIFICATION_API_BASE . 'token';
$body = [
'site' => [
'type' => 'SITE',
'identifier' => $site_url,
],
'verificationMethod' => 'META',
];
$result = $this->call_site_verification_api( $url, 'POST', $body );
if ( isset( $result['error'] ) ) {
return $result;
}
if ( ! isset( $result['token'] ) ) {
return [
'error' => true,
'message' => __( 'No verification token received', 'surerank' ),
'code' => 400,
];
}
// Extract token from HTML meta tag if needed.
$token = $result['token'];
if ( strpos( $token, '<meta' ) !== false ) {
// Extract content attribute from meta tag.
preg_match( '/content="([^"]*)"/', $token, $matches );
if ( isset( $matches[1] ) ) {
$token = $matches[1];
}
}
return [
'token' => $token,
];
}
/**
* Store Verification Token
*
* Stores the verification token for meta tag injection permanently
*
* @since 1.4.0
* @param string $token The verification token.
* @return void
*/
public function store_verification_token( $token ) {
update_option( self::VERIFICATION_TOKEN_OPTION, $token );
}
/**
* Get Stored Verification Token
*
* Gets the stored verification token from options
*
* @since 1.4.0
* @return string|false
*/
public function get_stored_verification_token() {
return get_option( self::VERIFICATION_TOKEN_OPTION, false );
}
/**
* Verify Site
*
* Verifies a site using Site Verification API
* Note: Verification may take 1-2 hours or up to 2 days to complete
*
* @since 1.4.0
* @param string $site_url The site URL to verify.
* @return array<string, mixed>|array<int, array<string, mixed>>
*/
public function verify_site( $site_url ) {
$url = self::GOOGLE_SITE_VERIFICATION_API_BASE . 'webResource?verificationMethod=META';
$body = [
'site' => [
'type' => 'SITE',
'identifier' => $site_url,
],
];
$result = $this->call_site_verification_api( $url, 'POST', $body );
if ( isset( $result['error'] ) ) {
$original_message = $result['original_message'] ?? $result['message'];
$http_code = $result['http_code'] ?? $result['code'] ?? 0;
if ( $http_code === 400 ) {
$error_details = [];
if ( isset( $result['original_message'] ) ) {
$decoded_error = json_decode( $result['original_message'], true );
if ( is_array( $decoded_error ) && isset( $decoded_error['error'] ) ) {
$error_details = $decoded_error['error'];
}
}
$error_reason = $error_details['errors'][0]['reason'] ?? '';
if ( $error_reason === 'badRequest' ) {
return [
'pending' => true,
'success' => false,
'message' => __( 'Site verification is pending. Google needs time to crawl and verify your site. This may take 1-2 hours or up to 2 days.', 'surerank' ),
'original_message' => $original_message,
];
}
}
return $result;
}
return [
'success' => true,
'message' => __( 'Site verified successfully', 'surerank' ),
];
}
/**
* Add Site
*
* Adds a site to Google Search Console
*
* @since 1.4.0
* @param string $site_url The site URL to add.
* @return array<string, mixed>|array<int, array<string, mixed>>
*/
public function add_site( $site_url ) {
$url = Controller::GOOGLE_ANALYTICS_API_BASE . 'sites/' . urlencode( $site_url );
$result = GoogleConsole::get_instance()->call_api( $url, 'PUT', [] );
if ( isset( $result['error'] ) && $result['error'] ) {
return $result;
}
return [
'success' => true,
'message' => __( 'Site added successfully', 'surerank' ),
];
}
/**
* Auto Create and Verify Property
*
* Creates and verifies a Search Console property following the documented flow
* Simplified version that only handles URL-prefix properties since subdomain logic moved to frontend
*
* @since 1.4.0
* @return array<string, mixed>|array<int, array<string, mixed>>
*/
public function auto_create_and_verify_property() {
return $this->perform_verification( true );
}
/**
* Verify Existing Property
*
* Verifies an existing Search Console property that's already added but not verified
*
* @since 1.4.0
* @return array<string, mixed>|array<int, array<string, mixed>>
*/
public function verify_existing_property() {
return $this->perform_verification( false );
}
/**
* Perform Verification Process
*
* Common method to handle verification for both creating new and verifying existing properties
*
* @since 1.4.0
* @param bool $add_site Whether to add the site to Search Console before verification.
* @return array<string, mixed>|array<int, array<string, mixed>>
*/
private function perform_verification( $add_site = false ) {
$property_url = $this->get_site_url();
// Step 1: Get verification token from Site Verification API.
$verification_token = $this->get_verification_token( $property_url );
if ( isset( $verification_token['error'] ) ) {
return $verification_token;
}
// Step 2: Store verification token for meta tag injection.
$this->store_verification_token( $verification_token['token'] );
// Step 3: Add site to Search Console if required.
if ( $add_site ) {
$add_result = $this->add_site( $property_url );
if ( isset( $add_result['error'] ) ) {
return $add_result;
}
}
// Step 4: Verify the property using Site Verification API.
$verify_result = $this->verify_site( $property_url );
if ( isset( $verify_result['error'] ) ) {
return $verify_result;
}
// Step 5: Update credentials with the new site URL.
$credentials = Auth::get_instance()->get_credentials( null );
$credentials['site_url'] = $property_url;
Auth::get_instance()->save_credentials( $credentials );
// Handle pending verification case.
if ( isset( $verify_result['pending'] ) && $verify_result['pending'] ) {
$message = $add_site
? __( 'Property created successfully. Verification is pending and may take 1-2 hours or up to 2 days.', 'surerank' )
: __( 'Verification is pending and may take 1-2 hours or up to 2 days.', 'surerank' );
return [
'success' => true,
'pending' => true,
'message' => $message,
'site_url' => $property_url,
];
}
$message = $add_site
? __( 'Property created and verified successfully', 'surerank' )
: __( 'Property verified successfully', 'surerank' );
return [
'success' => true,
'message' => $message,
'site_url' => $property_url,
];
}
/**
* Get Site URL for Verification
*
* Gets the site URL to use for verification
*
* @since 1.4.0
* @return string
*/
private function get_site_url() {
$site_url = get_site_url();
return str_replace( 'http://', 'https://', rtrim( $site_url, '/' ) ) . '/';
}
}