File: /var/www/vhosts/uyarreklam.com.tr/httpdocs/Ads.php.tar
vhosts/uyarreklam.com.tr/httpdocs/wp-content/plugins/google-listings-and-ads/src/API/Google/Ads.php 0000644 00000025013 15155401527 0030670 0 ustar 00 var/www <?php
declare( strict_types=1 );
namespace Automattic\WooCommerce\GoogleListingsAndAds\API\Google;
use Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query\AdsAccountAccessQuery;
use Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query\AdsAccountQuery;
use Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query\AdsBillingStatusQuery;
use Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query\AdsProductLinkInvitationQuery;
use Automattic\WooCommerce\GoogleListingsAndAds\Exception\ExceptionWithResponseData;
use Automattic\WooCommerce\GoogleListingsAndAds\Google\Ads\GoogleAdsClient;
use Automattic\WooCommerce\GoogleListingsAndAds\Options\OptionsAwareInterface;
use Automattic\WooCommerce\GoogleListingsAndAds\Options\OptionsAwareTrait;
use Automattic\WooCommerce\GoogleListingsAndAds\Options\OptionsInterface;
use Exception;
use Google\Ads\GoogleAds\Util\V18\ResourceNames;
use Google\Ads\GoogleAds\V18\Enums\AccessRoleEnum\AccessRole;
use Google\Ads\GoogleAds\V18\Enums\ProductLinkInvitationStatusEnum\ProductLinkInvitationStatus;
use Google\Ads\GoogleAds\V18\Resources\ProductLinkInvitation;
use Google\Ads\GoogleAds\V18\Services\ListAccessibleCustomersRequest;
use Google\Ads\GoogleAds\V18\Services\UpdateProductLinkInvitationRequest;
use Google\ApiCore\ApiException;
use Google\ApiCore\ValidationException;
defined( 'ABSPATH' ) || exit;
/**
* Class Ads
*
* @package Automattic\WooCommerce\GoogleListingsAndAds\API\Google
*/
class Ads implements OptionsAwareInterface {
use ExceptionTrait;
use OptionsAwareTrait;
/**
* The Google Ads Client.
*
* @var GoogleAdsClient
*/
protected $client;
/**
* Ads constructor.
*
* @param GoogleAdsClient $client
*/
public function __construct( GoogleAdsClient $client ) {
$this->client = $client;
}
/**
* Get Ads accounts associated with the connected Google account.
*
* @return array
* @throws ExceptionWithResponseData When an ApiException is caught.
*/
public function get_ads_accounts(): array {
try {
$customers = $this->client->getCustomerServiceClient()->listAccessibleCustomers( new ListAccessibleCustomersRequest() );
$accounts = [];
foreach ( $customers->getResourceNames() as $name ) {
$account = $this->get_account_details( $name );
if ( $account ) {
$accounts[] = $account;
}
}
return $accounts;
} catch ( ApiException $e ) {
do_action( 'woocommerce_gla_ads_client_exception', $e, __METHOD__ );
$errors = $this->get_exception_errors( $e );
// Return an empty list if the user has not signed up to ads yet.
if ( isset( $errors['NOT_ADS_USER'] ) ) {
return [];
}
throw new ExceptionWithResponseData(
/* translators: %s Error message */
sprintf( __( 'Error retrieving accounts: %s', 'google-listings-and-ads' ), reset( $errors ) ),
$this->map_grpc_code_to_http_status_code( $e ),
null,
[ 'errors' => $errors ]
);
}
}
/**
* Get billing status.
*
* @return string
*/
public function get_billing_status(): string {
$ads_id = $this->options->get_ads_id();
if ( ! $ads_id ) {
return BillingSetupStatus::UNKNOWN;
}
try {
$results = ( new AdsBillingStatusQuery() )
->set_client( $this->client, $this->options->get_ads_id() )
->get_results();
foreach ( $results->iterateAllElements() as $row ) {
$billing_setup = $row->getBillingSetup();
$status = BillingSetupStatus::label( $billing_setup->getStatus() );
return apply_filters( 'woocommerce_gla_ads_billing_setup_status', $status, $ads_id );
}
} catch ( ApiException | ValidationException $e ) {
// Do not act upon error as we might not have permission to access this account yet.
if ( 'PERMISSION_DENIED' !== $e->getStatus() ) {
do_action( 'woocommerce_gla_ads_client_exception', $e, __METHOD__ );
}
}
return apply_filters( 'woocommerce_gla_ads_billing_setup_status', BillingSetupStatus::UNKNOWN, $ads_id );
}
/**
* Accept the pending approval link sent from a merchant account.
*
* @param int $merchant_id Merchant Center account id.
* @throws Exception When the pending approval link can not be found.
*/
public function accept_merchant_link( int $merchant_id ) {
$link = $this->get_merchant_link( $merchant_id, 10 );
$request = new UpdateProductLinkInvitationRequest();
$request->setCustomerId( $this->options->get_ads_id() );
$request->setResourceName( $link->getResourceName() );
$request->setProductLinkInvitationStatus( ProductLinkInvitationStatus::ACCEPTED );
$this->client->getProductLinkInvitationServiceClient()->updateProductLinkInvitation( $request );
}
/**
* Check if we have access to the ads account.
*
* @param string $email Email address of the connected account.
*
* @return bool
*/
public function has_access( string $email ): bool {
$ads_id = $this->options->get_ads_id();
try {
$results = ( new AdsAccountAccessQuery() )
->set_client( $this->client, $ads_id )
->where( 'customer_user_access.email_address', $email )
->get_results();
foreach ( $results->iterateAllElements() as $row ) {
$access = $row->getCustomerUserAccess();
if ( AccessRole::ADMIN === $access->getAccessRole() ) {
return true;
}
}
} catch ( ApiException $e ) {
do_action( 'woocommerce_gla_ads_client_exception', $e, __METHOD__ );
}
return false;
}
/**
* Get the ads account currency.
*
* @since 1.4.1
*
* @return string
*/
public function get_ads_currency(): string {
// Retrieve account currency from the API if we haven't done so previously.
if ( $this->options->get_ads_id() && ! $this->options->get( OptionsInterface::ADS_ACCOUNT_CURRENCY ) ) {
$this->request_ads_currency();
}
return strtoupper( $this->options->get( OptionsInterface::ADS_ACCOUNT_CURRENCY ) ?? get_woocommerce_currency() );
}
/**
* Request the Ads Account currency, and cache it as an option.
*
* @since 1.1.0
*
* @return boolean
*/
public function request_ads_currency(): bool {
try {
$ads_id = $this->options->get_ads_id();
$account = ResourceNames::forCustomer( $ads_id );
$customer = ( new AdsAccountQuery() )
->set_client( $this->client, $ads_id )
->columns( [ 'customer.currency_code' ] )
->where( 'customer.resource_name', $account, '=' )
->get_result()
->getCustomer();
$currency = $customer->getCurrencyCode();
} catch ( ApiException $e ) {
do_action( 'woocommerce_gla_ads_client_exception', $e, __METHOD__ );
$currency = null;
}
return $this->options->update( OptionsInterface::ADS_ACCOUNT_CURRENCY, $currency );
}
/**
* Save the Ads account currency to the same value as the Store currency.
*
* @since 1.1.0
*
* @return boolean
*/
public function use_store_currency(): bool {
return $this->options->update( OptionsInterface::ADS_ACCOUNT_CURRENCY, get_woocommerce_currency() );
}
/**
* Convert ads ID from a resource name to an int.
*
* @param string $name Resource name containing ID number.
*
* @return int
*/
public function parse_ads_id( string $name ): int {
return absint( str_replace( 'customers/', '', $name ) );
}
/**
* Update the Ads ID to use for requests.
*
* @param int $id Ads ID number.
*
* @return bool
*/
public function update_ads_id( int $id ): bool {
return $this->options->update( OptionsInterface::ADS_ID, $id );
}
/**
* Returns true if the Ads id exists in the options.
*
* @return bool
*/
public function ads_id_exists(): bool {
return ! empty( $this->options->get( OptionsInterface::ADS_ID ) );
}
/**
* Update the billing flow URL so we can retrieve it again later.
*
* @param string $url Billing flow URL.
*
* @return bool
*/
public function update_billing_url( string $url ): bool {
return $this->options->update( OptionsInterface::ADS_BILLING_URL, $url );
}
/**
* Update the OCID for the account so that we can reference it later in order
* to link to accept invite link or to send customer to conversion settings page
* in their account.
*
* @param string $url Billing flow URL.
*
* @return bool
*/
public function update_ocid_from_billing_url( string $url ): bool {
$query_string = wp_parse_url( $url, PHP_URL_QUERY );
// Return if no params.
if ( empty( $query_string ) ) {
return false;
}
parse_str( $query_string, $params );
if ( empty( $params['ocid'] ) ) {
return false;
}
return $this->options->update( OptionsInterface::ADS_ACCOUNT_OCID, $params['ocid'] );
}
/**
* Fetch the account details.
* Returns null for any account that fails or is not the right type.
*
* @param string $account Customer resource name.
* @return null|array
*/
private function get_account_details( string $account ): ?array {
try {
$customer = ( new AdsAccountQuery() )
->set_client( $this->client, $this->parse_ads_id( $account ) )
->where( 'customer.resource_name', $account, '=' )
->get_result()
->getCustomer();
if ( ! $customer || $customer->getManager() || $customer->getTestAccount() ) {
return null;
}
return [
'id' => $customer->getId(),
'name' => $customer->getDescriptiveName(),
];
} catch ( ApiException $e ) {
do_action( 'woocommerce_gla_ads_client_exception', $e, __METHOD__ );
}
return null;
}
/**
* Get the pending approval link sent from a Google Merchant account.
*
* The invitation link may not be available in Google Ads immediately after
* the invitation is sent from Google Merchant Center, so this method offers
* a parameter to specify the number of retries.
*
* @param int $merchant_id Merchant Center account id.
* @param int $attempts_left The number of attempts left to get the link.
*
* @return ProductLinkInvitation
* @throws Exception When the pending approval link can not be found.
*/
private function get_merchant_link( int $merchant_id, int $attempts_left = 0 ): ProductLinkInvitation {
$res = ( new AdsProductLinkInvitationQuery() )
->set_client( $this->client, $this->options->get_ads_id() )
->where( 'product_link_invitation.status', ProductLinkInvitationStatus::name( ProductLinkInvitationStatus::PENDING_APPROVAL ) )
->get_results();
foreach ( $res->iterateAllElements() as $row ) {
$link = $row->getProductLinkInvitation();
$mc = $link->getMerchantCenter();
$mc_id = $mc->getMerchantCenterId();
if ( absint( $mc_id ) === $merchant_id ) {
return $link;
}
}
if ( $attempts_left > 0 ) {
sleep( 1 );
return $this->get_merchant_link( $merchant_id, $attempts_left - 1 );
}
throw new Exception( __( 'Unable to find the pending approval link sent from the Merchant Center account', 'google-listings-and-ads' ) );
}
}