765 lines
32 KiB
PHP
765 lines
32 KiB
PHP
<?php
|
|
|
|
namespace app\service;
|
|
|
|
use app\util\Helper;
|
|
use app\util\ArgumentNames;
|
|
use app\util\ArgumentParser;
|
|
use Google\Ads\GoogleAds\Lib\OAuth2TokenBuilder;
|
|
use Google\Ads\GoogleAds\Lib\V18\GoogleAdsClient;
|
|
use Google\Ads\GoogleAds\Lib\V18\GoogleAdsClientBuilder;
|
|
use Google\Ads\GoogleAds\Lib\V18\GoogleAdsException;
|
|
use Google\Ads\GoogleAds\Lib\V18\GoogleAdsServerStreamDecorator;
|
|
use Google\Ads\GoogleAds\Util\FieldMasks;
|
|
use Google\Ads\GoogleAds\Util\V18\ResourceNames;
|
|
use Google\Ads\GoogleAds\V18\Enums\AccessRoleEnum\AccessRole;
|
|
use Google\Ads\GoogleAds\V18\Enums\ManagerLinkStatusEnum\ManagerLinkStatus;
|
|
use Google\Ads\GoogleAds\V18\Errors\GoogleAdsError;
|
|
use Google\Ads\GoogleAds\V18\Resources\CustomerClient;
|
|
use Google\Ads\GoogleAds\V18\Resources\CustomerUserAccess;
|
|
use Google\Ads\GoogleAds\V18\Services\Client\CustomerServiceClient;
|
|
|
|
//use Google\Ads\GoogleAds\V18\Services\CustomerServiceClient;
|
|
use Google\Ads\GoogleAds\V18\Services\CustomerUserAccessOperation;
|
|
use Google\Ads\GoogleAds\V18\Services\GoogleAdsRow;
|
|
use Google\Ads\GoogleAds\V18\Services\ListAccessibleCustomersRequest;
|
|
use Google\Ads\GoogleAds\V18\Services\MutateCustomerUserAccessRequest;
|
|
use Google\Ads\GoogleAds\V18\Services\SearchGoogleAdsStreamRequest;
|
|
use Google\Ads\GoogleAds\V18\Resources\CustomerClientLink;
|
|
use Google\Ads\GoogleAds\V18\Resources\CustomerManagerLink;
|
|
use Google\Ads\GoogleAds\V18\Services\CustomerClientLinkOperation;
|
|
use Google\Ads\GoogleAds\V18\Services\CustomerManagerLinkOperation;
|
|
use Google\Ads\GoogleAds\V18\Services\MutateCustomerClientLinkRequest;
|
|
use Google\Ads\GoogleAds\V18\Services\MutateCustomerManagerLinkRequest;
|
|
use Google\Ads\GoogleAds\V18\Services\SearchGoogleAdsRequest;
|
|
use Google\ApiCore\ApiException;
|
|
|
|
class GoogleAdsAccountService extends BaseService
|
|
{
|
|
// private $googleAdsClient;
|
|
// private $customerId;
|
|
// private const NUMBER_OF_CAMPAIGNS_TO_ADD = 1;
|
|
// private $loginCustomerId; // 增加 login-customer-id 属性
|
|
|
|
// Stores the mapping from the root customer IDs (the ones that will be used as a start point
|
|
// for printing each hierarchy) to their `CustomerClient` objects.
|
|
private static array $rootCustomerClients = []; //必须在入口初始化空数组
|
|
|
|
public function __construct()
|
|
{
|
|
// $this->customerId = getenv('GOOGLE_ADS_CUSTOMER_ID');
|
|
//
|
|
// // OAuth2 Token Authentication
|
|
// $oAuth2Credential = (new OAuth2TokenBuilder())->fromFile()->build();
|
|
//
|
|
// // Google Ads Client initialization
|
|
// $this->googleAdsClient = (new GoogleAdsClientBuilder())
|
|
// ->fromFile()
|
|
// ->withOAuth2Credential($oAuth2Credential)
|
|
// ->build();
|
|
}
|
|
|
|
/**
|
|
* Runs the example.
|
|
*
|
|
* @param $options
|
|
* This example assumes that the same credentials will work for both customers,
|
|
* but that may not be the case. If you need to use different credentials
|
|
* for each customer, then you may either update the client configuration or
|
|
* instantiate the clients accordingly, one for each set of credentials. Always make
|
|
* sure to update the configuration before fetching any services you need to use.
|
|
* // * @return mixed
|
|
* @throws ApiException
|
|
*/
|
|
public function runLinkManagerToClient($options)
|
|
{
|
|
|
|
// Extends an invitation to the client while authenticating as the manager.
|
|
$managerCustomerId = $options['manager_customer_id'];
|
|
$clientCustomerId = $options['client_customer_id'];
|
|
|
|
|
|
// Extends an invitation to the client while authenticating as the manager.
|
|
$customerClientLinkResourceName = self::createInvitation(
|
|
$managerCustomerId,
|
|
$clientCustomerId
|
|
|
|
);
|
|
|
|
// Retrieves the manager link information.
|
|
$managerLinkResourceName = self::getManagerLinkResourceName(
|
|
$managerCustomerId,
|
|
$clientCustomerId,
|
|
$customerClientLinkResourceName
|
|
);
|
|
|
|
// Accepts the manager's invitation while authenticating as the client.
|
|
return self::acceptInvitation($clientCustomerId, $managerLinkResourceName);
|
|
|
|
|
|
}
|
|
|
|
/**
|
|
* Extends an invitation from a manager customer to a client customer.
|
|
*
|
|
* @param int $managerCustomerId the manager customer ID
|
|
* @param int $clientCustomerId the customer ID
|
|
* @return string the resource name of the customer client link created for the invitation
|
|
*/
|
|
public function createInvitation(
|
|
int $managerCustomerId,
|
|
int $clientCustomerId
|
|
)
|
|
{
|
|
|
|
// Creates a client with the manager customer ID as login customer ID.
|
|
$googleAdsClient = $this->createGoogleAdsClient($managerCustomerId);
|
|
|
|
// Creates a customer client link.
|
|
$customerClientLink = new CustomerClientLink([
|
|
// Sets the client customer to invite.
|
|
'client_customer' => ResourceNames::forCustomer($clientCustomerId),
|
|
'status' => ManagerLinkStatus::PENDING
|
|
]);
|
|
|
|
// Creates a customer client link operation for creating the one above.
|
|
$customerClientLinkOperation = new CustomerClientLinkOperation();
|
|
$customerClientLinkOperation->setCreate($customerClientLink);
|
|
|
|
// Issues a mutate request to create the customer client link.
|
|
$customerClientLinkServiceClient = $googleAdsClient->getCustomerClientLinkServiceClient();
|
|
$response = $customerClientLinkServiceClient->mutateCustomerClientLink(
|
|
MutateCustomerClientLinkRequest::build(
|
|
$managerCustomerId,
|
|
$customerClientLinkOperation
|
|
)
|
|
);
|
|
|
|
// Prints the result.
|
|
$customerClientLinkResourceName = $response->getResult()->getResourceName();
|
|
printf(
|
|
"An invitation has been extended from the manager customer %d" .
|
|
" to the client customer %d with the customer client link resource name '%s'.%s",
|
|
$managerCustomerId,
|
|
$clientCustomerId,
|
|
$customerClientLinkResourceName,
|
|
PHP_EOL
|
|
);
|
|
|
|
// Returns the resource name of the created customer client link.
|
|
return $customerClientLinkResourceName;
|
|
}
|
|
|
|
/**
|
|
* Retrieves the manager link resource name of a customer client link given its resource name.
|
|
*
|
|
* @param int $managerCustomerId the manager customer ID
|
|
* @param int $clientCustomerId the customer ID
|
|
* @param string $customerClientLinkResourceName the customer client link resource name
|
|
* @return string the manager link resource name
|
|
*/
|
|
public function getManagerLinkResourceName(
|
|
int $managerCustomerId,
|
|
int $clientCustomerId,
|
|
string $customerClientLinkResourceName
|
|
)
|
|
{
|
|
// Creates a client with the manager customer ID as login customer ID.
|
|
$googleAdsClient = $this->createGoogleAdsClient($managerCustomerId);
|
|
|
|
// Creates the query.
|
|
$query = "SELECT customer_client_link.manager_link_id FROM customer_client_link" .
|
|
" WHERE customer_client_link.resource_name = '$customerClientLinkResourceName'";
|
|
|
|
// Issues a search request.
|
|
$googleAdsServiceClient = $googleAdsClient->getGoogleAdsServiceClient();
|
|
$response = $googleAdsServiceClient->search(
|
|
SearchGoogleAdsRequest::build($managerCustomerId, $query)
|
|
);
|
|
|
|
// Gets the ID and resource name associated to the manager link found.
|
|
$managerLinkId = $response->getIterator()->current()
|
|
->getCustomerClientLink()
|
|
->getManagerLinkId();
|
|
$managerLinkResourceName = ResourceNames::forCustomerManagerLink(
|
|
$clientCustomerId,
|
|
$managerCustomerId,
|
|
$managerLinkId
|
|
);
|
|
|
|
// Prints the result.
|
|
printf(
|
|
"Retrieved the manager link of the customer client link:" .
|
|
" its ID is %d and its resource name is '%s'.%s",
|
|
$managerLinkId,
|
|
$managerLinkResourceName,
|
|
PHP_EOL
|
|
);
|
|
|
|
// Returns the resource name of the manager link found.
|
|
return $managerLinkResourceName;
|
|
}
|
|
|
|
/**
|
|
* Accepts an invitation.
|
|
*
|
|
* @param int $clientCustomerId the customer ID
|
|
* @param string $managerLinkResourceName the resource name of the manager link to accept
|
|
*/
|
|
public function acceptInvitation(
|
|
int $clientCustomerId,
|
|
string $managerLinkResourceName
|
|
)
|
|
{
|
|
// Creates a client with the client customer ID as login customer ID.
|
|
$googleAdsClient = $this->createGoogleAdsClient($clientCustomerId);
|
|
|
|
// Creates the customer manager link with the updated status.
|
|
$customerManagerLink = new CustomerManagerLink();
|
|
$customerManagerLink->setResourceName($managerLinkResourceName);
|
|
$customerManagerLink->setStatus(ManagerLinkStatus::ACTIVE);
|
|
|
|
// Creates a customer manager link operation for updating the one above.
|
|
$customerManagerLinkOperation = new CustomerManagerLinkOperation();
|
|
$customerManagerLinkOperation->setUpdate($customerManagerLink);
|
|
$customerManagerLinkOperation->setUpdateMask(
|
|
FieldMasks::allSetFieldsOf($customerManagerLink)
|
|
);
|
|
|
|
// Issues a mutate request to update the customer manager link.
|
|
$customerManagerLinkServiceClient =
|
|
$googleAdsClient->getCustomerManagerLinkServiceClient();
|
|
$response = $customerManagerLinkServiceClient->mutateCustomerManagerLink(
|
|
MutateCustomerManagerLinkRequest::build(
|
|
$clientCustomerId,
|
|
[$customerManagerLinkOperation]
|
|
)
|
|
);
|
|
|
|
// Prints the result.
|
|
printf(
|
|
"The client %d accepted the invitation with the resource name '%s'.%s",
|
|
$clientCustomerId,
|
|
$response->getResults()[0]->getResourceName(),
|
|
PHP_EOL
|
|
);
|
|
return $response->getResults()[0]->getResourceName();
|
|
}
|
|
// [END link_manager_to_client]
|
|
|
|
/**
|
|
* Creates a Google Ads client based on the default configuration file
|
|
* and a given login customer id.
|
|
*
|
|
* @param int $thirdUserId thirdUser
|
|
* @return GoogleAdsClient the created client
|
|
*/
|
|
// public function createGoogleAdsClient(int $thirdUserId)
|
|
public function createGoogleAdsClient($refreshToken)
|
|
{
|
|
|
|
// 从数据库获取 access_token
|
|
// $refreshToken = $this->getRefreshTokenFromDatabase($thirdUserId);
|
|
|
|
if (!$refreshToken) {
|
|
throw new \Exception("Access token not found for advertiserId: " . $refreshToken);
|
|
}
|
|
|
|
// OAuth2 Token Authentication
|
|
$oAuth2Credential = (new OAuth2TokenBuilder())
|
|
->fromFile() // 如果需要从文件获取其他配置,可以继续使用 fromFile()
|
|
->withRefreshToken($refreshToken) // 使用动态获取的 access_token
|
|
->build();
|
|
|
|
|
|
// Builds and returns the Google Ads client
|
|
return (new GoogleAdsClientBuilder())
|
|
// Sets the properties based on the default properties file
|
|
->fromFile()
|
|
// eUses the OAuth2 credentials crated above.
|
|
->withOAuth2Credential($oAuth2Credential)
|
|
// Overrides the login customer ID with the given one.
|
|
->build();
|
|
|
|
|
|
}
|
|
|
|
/**
|
|
* Creates a Google Ads client based on the default configuration file
|
|
* and a given login customer id.
|
|
*
|
|
* @param int $loginCustomerId the login customer ID
|
|
* @return GoogleAdsClient the created client
|
|
*/
|
|
// public function createGoogleAdsClientWithloginCustomerId(int $thirdUserId,int $loginCustomerId)
|
|
public function createGoogleAdsClientWithloginCustomerId($refreshToken, int $loginCustomerId)
|
|
{
|
|
// $advertiserId = getenv('GOOGLE_ADS_CUSTOMER_ID');
|
|
|
|
// 从数据库获取 access_token
|
|
// $refreshToken = $this->getRefreshTokenFromDatabase($thirdUserId);
|
|
|
|
if (!$refreshToken) {
|
|
throw new \Exception("Access token not found for advertiserId: " . $refreshToken);
|
|
}
|
|
// OAuth2 Token Authentication
|
|
$oAuth2Credential = (new OAuth2TokenBuilder())
|
|
->fromFile() // 如果需要从文件获取其他配置,可以继续使用 fromFile()
|
|
->withRefreshToken($refreshToken) // 使用动态获取的 access_token
|
|
->build();
|
|
|
|
// Builds and returns the Google Ads client
|
|
return (
|
|
new GoogleAdsClientBuilder())
|
|
// Sets the properties based on the default properties file
|
|
->fromFile()
|
|
// eUses the OAuth2 credentials crated above.
|
|
->withOAuth2Credential($oAuth2Credential)
|
|
// Overrides the login customer ID with the given one.
|
|
->withLoginCustomerId($loginCustomerId)
|
|
->build();
|
|
}
|
|
|
|
/**
|
|
* Runs the example.
|
|
*
|
|
* @param GoogleAdsClient $googleAdsClient the Google Ads API client
|
|
*/
|
|
// [START list_accessible_customers]
|
|
public function runListAccessibleCustomers($option)
|
|
{
|
|
// $loginCustomerId = $option['customer_id'];
|
|
$refreshToken = $option['refresh_token'];
|
|
// Creates a client with the manager customer ID as login customer ID.
|
|
$googleAdsClient = $this->createGoogleAdsClient($refreshToken);
|
|
|
|
$customerServiceClient = $googleAdsClient->getCustomerServiceClient();
|
|
|
|
// Issues a request for listing all accessible customers.
|
|
$accessibleCustomers =
|
|
$customerServiceClient->listAccessibleCustomers(new ListAccessibleCustomersRequest());
|
|
|
|
$accessibleCustomerIds = [];
|
|
foreach ($accessibleCustomers->getResourceNames() as $customerResourceName) {
|
|
$customer = CustomerServiceClient::parseName($customerResourceName)['customer_id'];
|
|
print $customer . PHP_EOL;
|
|
$accessibleCustomerIds[] = intval($customer);
|
|
}
|
|
return $accessibleCustomerIds;
|
|
|
|
// print 'Total results: ' . count($accessibleCustomers->getResourceNames()) . PHP_EOL;
|
|
|
|
// $resourceNameArray = [];
|
|
// // Iterates over all accessible customers' resource names and prints them.
|
|
// foreach ($accessibleCustomers->getResourceNames() as $resourceName) {
|
|
// /** @var string $resourceName */
|
|
// printf("Customer resource name: '%s'%s", $resourceName, PHP_EOL);
|
|
// $resourceNameArray[] = $resourceName;
|
|
// }
|
|
// return $resourceNameArray;
|
|
}
|
|
// [END list_accessible_customers]
|
|
|
|
|
|
/**
|
|
* Runs the example. 没调用
|
|
*
|
|
* @param GoogleAdsClient $googleAdsClient the Google Ads API client
|
|
* @param int $customerId the customer ID
|
|
* @param string $emailAddress the email address of the user whose access role should be updated
|
|
* @param string $accessRole the updated access role
|
|
*/
|
|
public function runGetAccountAccess(
|
|
$option)
|
|
{
|
|
$managerCustomerId = isset($option['manager_customer_id']) ? (int)$option['manager_customer_id'] : null;
|
|
$loginCustomerId = isset($option['login_customer_id']) ? (int)$option['login_customer_id'] : null;
|
|
$refreshToken = isset($option['refresh_token']) ? $option['refresh_token'] : null;
|
|
// $thirdUserId = (int)$option['third_user_id'];
|
|
|
|
// Creates a client with the manager customer ID as login customer ID.
|
|
$googleAdsClient = $this->createGoogleAdsClientWithloginCustomerId($refreshToken, $loginCustomerId);
|
|
|
|
$customerId = 8452924576;
|
|
$userId = $this->getUserAccess($googleAdsClient, $customerId, 's5O0z@example.com');
|
|
// if (!is_null($userId)) {
|
|
// $this->modifyUserAccess($googleAdsClient, $customerId, $userId, $accessRole);
|
|
// }
|
|
return $userId;
|
|
}
|
|
|
|
/**
|
|
* Gets the customer user access given an email address.
|
|
*
|
|
* @param GoogleAdsClient $googleAdsClient the Google Ads API client
|
|
* @param int $customerId the customer ID
|
|
* @param string $emailAddress the email address of the user whose access role should be updated
|
|
* @return int|null the user ID if a customer is found, or null if no matching customers were
|
|
* found
|
|
*/
|
|
public function getUserAccess(
|
|
GoogleAdsClient $googleAdsClient,
|
|
int $customerId,
|
|
string $emailAddress
|
|
)
|
|
{
|
|
$googleAdsServiceClient = $googleAdsClient->getGoogleAdsServiceClient();
|
|
// Creates a query that retrieves all customer user accesses.
|
|
// Use the LIKE query for filtering to ignore the text case for email address when
|
|
// searching for a match.
|
|
// $query = "SELECT customer_user_access.user_id, "
|
|
// . "customer_user_access.email_address, customer_user_access.access_role,"
|
|
// . "customer_user_access.access_creation_date_time FROM customer_user_access "
|
|
// . "WHERE customer_user_access.email_address LIKE '$emailAddress'";
|
|
$query = "SELECT customer_user_access.user_id, "
|
|
. "customer_user_access.email_address, customer_user_access.access_role,"
|
|
. "customer_user_access.access_creation_date_time FROM customer_user_access "
|
|
. "WHERE customer_user_access.user_id = $customerId";
|
|
// Issues a search request by to retrieve the customer user accesses.
|
|
$response =
|
|
$googleAdsServiceClient->search(SearchGoogleAdsRequest::build($customerId, $query));
|
|
if (iterator_count($response) > 0) {
|
|
/** @var CustomerUserAccess $customerUserAccess */
|
|
$customerUserAccess = $response->getIterator()->current()->getCustomerUserAccess();
|
|
printf(
|
|
"Customer user access with User ID = %d, Email Address = "
|
|
. "'%s', Access Role = '%s' and Creation Time = %s was found in "
|
|
. "Customer ID: %d.%s",
|
|
$customerUserAccess->getUserId(),
|
|
$customerUserAccess->getEmailAddress(),
|
|
AccessRole::name($customerUserAccess->getAccessRole()),
|
|
$customerUserAccess->getAccessCreationDateTime(),
|
|
$customerId,
|
|
PHP_EOL
|
|
);
|
|
return $customerUserAccess->getUserId();
|
|
} else {
|
|
print 'No customer user access with requested email was found.' . PHP_EOL;
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Modifies the user access role to a specified value.
|
|
*
|
|
* @param GoogleAdsClient $googleAdsClient the Google Ads API client
|
|
* @param int $customerId the customer ID
|
|
* @param int $userId ID of the user whose access role is modified
|
|
* @param string $accessRole the updated access role
|
|
*/
|
|
public function modifyUserAccess(
|
|
GoogleAdsClient $googleAdsClient,
|
|
int $customerId,
|
|
int $userId,
|
|
string $accessRole
|
|
)
|
|
{
|
|
// Creates the modified user access.
|
|
$customerUserAccess = new CustomerUserAccess([
|
|
'resource_name' => ResourceNames::forCustomerUserAccess($customerId, $userId),
|
|
'access_role' => AccessRole::value($accessRole)
|
|
]);
|
|
|
|
// Constructs an operation that will update the customer user access with the specified
|
|
// resource name, using the FieldMasks utility to derive the update mask. This mask tells
|
|
// the Google Ads API which attributes of the customer user access you want to change.
|
|
$customerUserAccessOperation = new CustomerUserAccessOperation();
|
|
$customerUserAccessOperation->setUpdate($customerUserAccess);
|
|
$customerUserAccessOperation->setUpdateMask(
|
|
FieldMasks::allSetFieldsOf($customerUserAccess)
|
|
);
|
|
|
|
// Issues a mutate request to update the customer user access.
|
|
$customerUserAccessServiceClient = $googleAdsClient->getCustomerUserAccessServiceClient();
|
|
$response = $customerUserAccessServiceClient->mutateCustomerUserAccess(
|
|
MutateCustomerUserAccessRequest::build($customerId, $customerUserAccessOperation)
|
|
);
|
|
|
|
// Prints the resource name of the updated customer user access.
|
|
printf(
|
|
"Successfully modified customer user access with resource name: '%s'%s",
|
|
$response->getResult()->getResourceName(),
|
|
PHP_EOL
|
|
);
|
|
}
|
|
|
|
|
|
/**
|
|
* 层级账号信息
|
|
*
|
|
*/
|
|
public function runGetAccountHierarchy(
|
|
$option
|
|
)
|
|
{
|
|
|
|
self::$rootCustomerClients = []; //初始化静态变量
|
|
|
|
$managerCustomerId = isset($option['manager_customer_id']) ? (int)$option['manager_customer_id'] : null;
|
|
$loginCustomerId = isset($option['login_customer_id']) ? (int)$option['login_customer_id'] : null;
|
|
$refreshToken = isset($option['refresh_token']) ? $option['refresh_token'] : null;
|
|
// $thirdUserId = (int)$option['third_user_id'];
|
|
|
|
// Creates a client with the manager customer ID as login customer ID.
|
|
$googleAdsClient = $this->createGoogleAdsClient($refreshToken);
|
|
|
|
// $customerServiceClient = $googleAdsClient->getCustomerServiceClient();
|
|
|
|
|
|
$rootCustomerIds = [];
|
|
if (is_null($managerCustomerId)) {
|
|
// We will get the account hierarchies for all accessible customers.
|
|
$rootCustomerIds = $this->getAccessibleCustomers($googleAdsClient);
|
|
} else {
|
|
// We will get only the hierarchy for the provided manager customer ID when it's
|
|
// provided.
|
|
$rootCustomerIds[] = $managerCustomerId;
|
|
}
|
|
|
|
$allHierarchies = [];
|
|
$accountsWithNoInfo = [];
|
|
|
|
// Constructs a map of account hierarchies.
|
|
foreach ($rootCustomerIds as $rootCustomerId) {
|
|
$customerClientToHierarchy =
|
|
$this->createCustomerClientToHierarchy($refreshToken, $loginCustomerId, $rootCustomerId);
|
|
if (is_null($customerClientToHierarchy)) {
|
|
$accountsWithNoInfo[] = $rootCustomerId;
|
|
} else {
|
|
$allHierarchies += $customerClientToHierarchy;
|
|
}
|
|
}
|
|
|
|
// Prints the IDs of any accounts that did not produce hierarchy information.
|
|
if (!empty($accountsWithNoInfo)) {
|
|
print
|
|
'Unable to retrieve information for the following accounts which are likely '
|
|
. 'either test accounts or accounts with setup issues. Please check the logs for '
|
|
. 'details:' . PHP_EOL;
|
|
foreach ($accountsWithNoInfo as $accountId) {
|
|
print $accountId . PHP_EOL;
|
|
}
|
|
print PHP_EOL;
|
|
}
|
|
$allAccounts = [];
|
|
// Prints the hierarchy information for all accounts for which there is hierarchy info
|
|
// available.
|
|
foreach ($allHierarchies as $rootCustomerId => $customerIdsToChildAccounts) {
|
|
// printf(
|
|
// "The hierarchy of customer ID %d is printed below:%s",
|
|
// $rootCustomerId,
|
|
// PHP_EOL
|
|
// );
|
|
// 获取所有账户的数组(包括根账户及其子账户)
|
|
$accounts = [];
|
|
self::getAccountHierarchy(
|
|
self::$rootCustomerClients[$rootCustomerId],
|
|
$customerIdsToChildAccounts,
|
|
0,
|
|
$accounts);
|
|
$allAccounts[$rootCustomerId] = $accounts;
|
|
|
|
// self::printAccountHierarchy(
|
|
// self::$rootCustomerClients[$rootCustomerId],
|
|
// $customerIdsToChildAccounts,
|
|
// 0
|
|
// );
|
|
// print PHP_EOL;
|
|
}
|
|
// dump($allAccounts);
|
|
return $allAccounts;
|
|
}
|
|
|
|
/**
|
|
* Creates a map between a customer client and each of its managers' mappings.
|
|
*
|
|
* @param int|null $loginCustomerId the login customer ID used to create the GoogleAdsClient
|
|
* @param int $rootCustomerId the ID of the customer at the root of the tree
|
|
* @return array|null a map between a customer client and each of its managers' mappings if the
|
|
* account hierarchy can be retrieved. If the account hierarchy cannot be retrieved, returns
|
|
* null
|
|
*/
|
|
public function createCustomerClientToHierarchy(
|
|
string $refreshToken,
|
|
?int $loginCustomerId,
|
|
int $rootCustomerId
|
|
): ?array
|
|
{
|
|
|
|
|
|
// Creates a client with the manager customer ID as login customer ID.
|
|
$googleAdsClient = $this->createGoogleAdsClientWithloginCustomerId($refreshToken, $loginCustomerId ?? $rootCustomerId);
|
|
|
|
// Creates the Google Ads Service client.
|
|
$googleAdsServiceClient = $googleAdsClient->getGoogleAdsServiceClient();
|
|
// Creates a query that retrieves all child accounts of the manager specified in search
|
|
// calls below.
|
|
$query = 'SELECT customer_client.client_customer, customer_client.level,'
|
|
. ' customer_client.manager,customer_client.test_account, customer_client.descriptive_name,'
|
|
. ' customer_client.currency_code, customer_client.time_zone,'
|
|
. ' customer_client.id FROM customer_client WHERE customer_client.level <= 1';
|
|
|
|
$rootCustomerClient = null;
|
|
// Adds the root customer ID to the list of IDs to be processed.
|
|
$managerCustomerIdsToSearch = [$rootCustomerId];
|
|
|
|
// Performs a breadth-first search algorithm to build an associative array mapping
|
|
// managers to their child accounts ($customerIdsToChildAccounts).
|
|
$customerIdsToChildAccounts = [];
|
|
|
|
while (!empty($managerCustomerIdsToSearch)) {
|
|
$customerIdToSearch = array_shift($managerCustomerIdsToSearch);
|
|
// Issues a search request.
|
|
/** @var GoogleAdsServerStreamDecorator $stream */
|
|
$stream = $googleAdsServiceClient->searchStream(SearchGoogleAdsStreamRequest::build(
|
|
$customerIdToSearch,
|
|
$query
|
|
));
|
|
|
|
// Iterates over all elements to get all customer clients under the specified customer's
|
|
// hierarchy.
|
|
foreach ($stream->iterateAllElements() as $googleAdsRow) {
|
|
/** @var GoogleAdsRow $googleAdsRow */
|
|
$customerClient = $googleAdsRow->getCustomerClient();
|
|
|
|
// Gets the CustomerClient object for the root customer in the tree.
|
|
if ($customerClient->getId() === $rootCustomerId) {
|
|
$rootCustomerClient = $customerClient;
|
|
self::$rootCustomerClients[$rootCustomerId] = $rootCustomerClient;
|
|
}
|
|
|
|
// The steps below map parent and children accounts. Continue here so that managers
|
|
// accounts exclude themselves from the list of their children accounts.
|
|
if ($customerClient->getId() === $customerIdToSearch) {
|
|
continue;
|
|
}
|
|
|
|
// For all level-1 (direct child) accounts that are a manager account, the above
|
|
// query will be run against them to create an associative array of managers to
|
|
// their child accounts for printing the hierarchy afterwards.
|
|
$customerIdsToChildAccounts[$customerIdToSearch][] = $customerClient;
|
|
// Checks if the child account is a manager itself so that it can later be processed
|
|
// and added to the map if it hasn't been already.
|
|
if ($customerClient->getManager()) {
|
|
// A customer can be managed by multiple managers, so to prevent visiting
|
|
// the same customer multiple times, we need to check if it's already in the
|
|
// map.
|
|
$alreadyVisited = array_key_exists(
|
|
$customerClient->getId(),
|
|
$customerIdsToChildAccounts
|
|
);
|
|
if (!$alreadyVisited && $customerClient->getLevel() === 1) {
|
|
array_push($managerCustomerIdsToSearch, $customerClient->getId());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return is_null($rootCustomerClient) ? null
|
|
: [$rootCustomerClient->getId() => $customerIdsToChildAccounts];
|
|
}
|
|
|
|
/**
|
|
* Retrieves a list of accessible customers with the provided set up credentials.
|
|
*
|
|
* @param GoogleAdsClient $googleAdsClient the Google Ads API client
|
|
* @return int[] the list of customer IDs
|
|
*/
|
|
public function getAccessibleCustomers(GoogleAdsClient $googleAdsClient): array
|
|
{
|
|
$accessibleCustomerIds = [];
|
|
// Issues a request for listing all customers accessible by this authenticated Google
|
|
// account.
|
|
$customerServiceClient = $googleAdsClient->getCustomerServiceClient();
|
|
$accessibleCustomers =
|
|
$customerServiceClient->listAccessibleCustomers(new ListAccessibleCustomersRequest());
|
|
|
|
print 'No manager customer ID is specified. The example will print the hierarchies of'
|
|
. ' all accessible customer IDs:' . PHP_EOL;
|
|
foreach ($accessibleCustomers->getResourceNames() as $customerResourceName) {
|
|
$customer = CustomerServiceClient::parseName($customerResourceName)['customer_id'];
|
|
print $customer . PHP_EOL;
|
|
$accessibleCustomerIds[] = intval($customer);
|
|
}
|
|
print PHP_EOL;
|
|
|
|
return $accessibleCustomerIds;
|
|
}
|
|
|
|
/**
|
|
* Prints the specified account's hierarchy using recursion.
|
|
*
|
|
* @param CustomerClient $customerClient the customer client whose info will be printed and
|
|
* its child accounts will be processed if it's a manager
|
|
* @param array $customerIdsToChildAccounts a map from customer IDs to child
|
|
* accounts
|
|
* @param int $depth the current depth we are printing from in the
|
|
* account hierarchy
|
|
*/
|
|
private static function printAccountHierarchy(
|
|
CustomerClient $customerClient,
|
|
array $customerIdsToChildAccounts,
|
|
int $depth
|
|
)
|
|
{
|
|
if ($depth === 0) {
|
|
print 'Customer ID (Descriptive Name, Currency Code, Time Zone, Manager, Test Account)' . PHP_EOL;
|
|
}
|
|
$customerId = $customerClient->getId();
|
|
print str_repeat('-', $depth * 2);
|
|
printf(
|
|
" %d ('%s', '%s', '%s', '%s', '%s')%s",
|
|
$customerId,
|
|
$customerClient->getDescriptiveName(),
|
|
$customerClient->getCurrencyCode(),
|
|
$customerClient->getTimeZone(),
|
|
$customerClient->getManager(),
|
|
$customerClient->getTestAccount(),
|
|
PHP_EOL
|
|
);
|
|
|
|
// Recursively call this function for all child accounts of $customerClient.
|
|
if (array_key_exists($customerId, $customerIdsToChildAccounts)) {
|
|
foreach ($customerIdsToChildAccounts[$customerId] as $childAccount) {
|
|
self::printAccountHierarchy($childAccount, $customerIdsToChildAccounts, $depth + 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
private static function getAccountHierarchy(
|
|
CustomerClient $customerClient,
|
|
array $customerIdsToChildAccounts,
|
|
int $depth,
|
|
array &$result = [] // 这里使用引用传递
|
|
)
|
|
{
|
|
// Store the current customer ID and descriptive name in the result array
|
|
$customerId = $customerClient->getId();
|
|
//如果$customerClient->getManager()是true则不记录到$result数组中
|
|
if (!$customerClient->getManager() && !$customerClient->getTestAccount()) {
|
|
$result[] = [
|
|
'account_id' => $customerId,
|
|
'account_name' => $customerClient->getDescriptiveName(),
|
|
// 'manager' => $customerClient->getManager(),
|
|
// 'test_account' => $customerClient->getTestAccount(),
|
|
'currency' => $customerClient->getCurrencyCode(),
|
|
// 'status' => $customerClient->getStatus(),
|
|
// 'level' => $customerClient->getLevel(),
|
|
// 'time_zone' => $customerClient->getTimeZone(),
|
|
];
|
|
}
|
|
|
|
// Recursively call this function for all child accounts of $customerClient.
|
|
if (array_key_exists($customerId, $customerIdsToChildAccounts)) {
|
|
foreach ($customerIdsToChildAccounts[$customerId] as $childAccount) {
|
|
// Recursively add the child account information
|
|
$result = self::getAccountHierarchy($childAccount, $customerIdsToChildAccounts, $depth + 1, $result);
|
|
}
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
|
|
}
|