<?php
namespace Automattic\WooCommerce\GoogleListingsAndAds\Google;
use Automattic\WooCommerce\GoogleListingsAndAds\Infrastructure\Service;
/**
* Helper class for Account request Review feature
*/
class RequestReviewStatuses implements Service {
public const ENABLED = 'ENABLED';
public const DISAPPROVED = 'DISAPPROVED';
public const WARNING = 'WARNING';
public const UNDER_REVIEW = 'UNDER_REVIEW';
public const PENDING_REVIEW = 'PENDING_REVIEW';
public const ONBOARDING = 'ONBOARDING';
public const APPROVED = 'APPROVED';
public const NO_OFFERS = 'NO_OFFERS_UPLOADED';
public const ELIGIBLE = 'ELIGIBLE';
public const MC_ACCOUNT_REVIEW_LIFETIME = MINUTE_IN_SECONDS * 20; // 20 minutes
/**
* Merges the different program statuses, issues and cooldown period date.
*
* @param array $response Associative array containing the response data from Google API
* @return array The computed status, with the issues and cooldown period.
*/
public function get_statuses_from_response( array $response ) {
$issues = [];
$cooldown = 0;
$status = null;
$valid_program_states = [ self::ENABLED, self::NO_OFFERS ];
$review_eligible_regions = [];
foreach ( $response as $program_type ) {
// In case any Program is with no offers we consider it Onboarding
if ( $program_type['data']['globalState'] === self::NO_OFFERS ) {
$status = self::ONBOARDING;
break;
}
// In case any Program is not enabled or there are no regionStatuses we return null status
if ( ! isset( $program_type['data']['regionStatuses'] ) || ! in_array( $program_type['data']['globalState'], $valid_program_states, true ) ) {
continue;
}
// Otherwise, we compute the new status, issues and cooldown period
foreach ( $program_type['data']['regionStatuses'] as $region_status ) {
$issues = array_merge( $issues, $region_status['reviewIssues'] ?? [] );
$cooldown = $this->maybe_update_cooldown_period( $region_status, $cooldown );
$status = $this->maybe_update_status( $region_status['eligibilityStatus'], $status );
$review_eligible_regions = $this->maybe_load_eligible_region( $region_status, $review_eligible_regions );
}
}
return [
'issues' => array_map( 'strtolower', array_values( array_unique( $issues ) ) ),
'cooldown' => $this->get_cooldown( $cooldown ), // add lifetime cache to cooldown time
'status' => $status,
'reviewEligibleRegions' => array_unique( $review_eligible_regions ),
];
}
/**
* Updates the cooldown period in case the new cooldown period date is available and later than the current cooldown period.
*
* @param array $region_status Associative array containing (maybe) a cooldown date property.
* @param int $cooldown Referenced current cooldown to compare with
*
* @return int The cooldown
*/
private function maybe_update_cooldown_period( $region_status, $cooldown ) {
if (
isset( $region_status['reviewIneligibilityReasonDetails'] ) &&
isset( $region_status['reviewIneligibilityReasonDetails']['cooldownTime'] )
) {
$region_cooldown = intval( strtotime( $region_status['reviewIneligibilityReasonDetails']['cooldownTime'] ) );
if ( ! $cooldown || $region_cooldown > $cooldown ) {
$cooldown = $region_cooldown;
}
}
return $cooldown;
}
/**
* Updates the status reference in case the new status has more priority.
*
* @param String $new_status New status to check has more priority than the current one
* @param String $status Referenced current status
*
* @return String The status
*/
private function maybe_update_status( $new_status, $status ) {
$status_priority_list = [
self::ONBOARDING, // highest priority
self::DISAPPROVED,
self::WARNING,
self::UNDER_REVIEW,
self::PENDING_REVIEW,
self::APPROVED,
];
$current_status_priority = array_search( $status, $status_priority_list, true );
$new_status_priority = array_search( $new_status, $status_priority_list, true );
if ( $new_status_priority !== false && ( is_null( $status ) || $current_status_priority > $new_status_priority ) ) {
return $new_status;
}
return $status;
}
/**
* Updates the regions where a request review is allowed.
*
* @param array $region_status Associative array containing the region eligibility.
* @param array $review_eligible_regions Indexed array with the current eligible regions.
*
* @return array The (maybe) modified $review_eligible_regions array
*/
private function maybe_load_eligible_region( array $region_status, array $review_eligible_regions ) {
if (
! empty( $region_status['regionCodes'] ) &&
isset( $region_status['reviewEligibilityStatus'] ) &&
$region_status['reviewEligibilityStatus'] === self::ELIGIBLE
) {
array_push( $review_eligible_regions, $region_status['regionCodes'][0] );
}
return $review_eligible_regions;
}
/**
* Allows a hook to modify the lifetime of the Account review data.
*
* @return int
*/
public function get_account_review_lifetime(): int {
return apply_filters( 'woocommerce_gla_mc_account_review_lifetime', self::MC_ACCOUNT_REVIEW_LIFETIME );
}
/**
* @param int $cooldown The cooldown in PHP format (seconds)
*
* @return int The cooldown in milliseconds and adding the lifetime cache
*/
private function get_cooldown( int $cooldown ) {
if ( $cooldown ) {
$cooldown = ( $cooldown + $this->get_account_review_lifetime() ) * 1000;
}
return $cooldown;
}
}