webman_ad/app/service/GoogleAdsAssetRelationService.php
2024-12-28 15:53:54 +08:00

735 lines
28 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace app\service;
use app\service\GoogleAdsClientService;
use app\model\ThirdUserAdvertiser;
use app\util\Helper;
use app\util\ArgumentNames;
use app\util\ArgumentParser;
//use Google\Ads\GoogleAds\Lib\V18\GoogleAdsClient;
//use Google\Ads\GoogleAds\Util\FieldMasks;
//use Google\Ads\GoogleAds\Util\V18\ResourceNames;
//use Google\Ads\GoogleAds\V18\Common\ResponsiveSearchAdInfo;
//use Google\Ads\GoogleAds\V18\Enums\AdGroupAdStatusEnum\AdGroupAdStatus;
//use Google\Ads\GoogleAds\V18\Enums\GoogleAdsFieldCategoryEnum\GoogleAdsFieldCategory;
//use Google\Ads\GoogleAds\V18\Enums\GoogleAdsFieldDataTypeEnum\GoogleAdsFieldDataType;
//use Google\Ads\GoogleAds\V18\Errors\GoogleAdsError;
//use Google\Ads\GoogleAds\V18\Resources\Ad;
//use Google\Ads\GoogleAds\V18\Resources\AdGroupAd;
//use Google\Ads\GoogleAds\V18\Resources\GoogleAdsField;
//use Google\Ads\GoogleAds\V18\Services\AdGroupAdOperation;
//use Google\Ads\GoogleAds\V18\Services\AdOperation;
//use Google\Ads\GoogleAds\V18\Services\MutateAdGroupAdsRequest;
//
//use Google\Ads\GoogleAds\V18\Common\AdTextAsset;
//use Google\Ads\GoogleAds\V18\Enums\ServedAssetFieldTypeEnum\ServedAssetFieldType;
//use Google\Ads\GoogleAds\V18\Services\GoogleAdsRow;
//use Google\Ads\GoogleAds\V18\Services\MutateAdsRequest;
//use Google\Ads\GoogleAds\V18\Services\SearchGoogleAdsFieldsRequest;
//use Google\Ads\GoogleAds\V18\Services\SearchGoogleAdsRequest;
//use Google\Ads\GoogleAds\V18\Services\SearchGoogleAdsStreamRequest;
//use Google\Protobuf\Internal\RepeatedField;
use think\facade\Db as ThinkDb;
use app\model\Ad as AdModel;
use app\model\Asset as AssetModel;
use app\model\AssetRelation as AssetRelationModel;
use Google\ApiCore\ApiException;
class GoogleAdsAssetRelationService extends BaseService
{
// private $googleAdsClient;
private $customerId;
public function __construct($customerId = null)
{
}
// 从数据库动态获取 google RefreshToken
// private function getRefreshTokenFromDatabase($advertiserId)
// {
// // 通过 advertiser_id 查询 ThirdUserAdvertiser联表查询 ThirdUser 数据
// $userAdvertiser = ThirdUserAdvertiser::with('googleUser') // 联表查询 user 关联
// ->where('advertiser_id', $advertiserId) // 根据 advertiser_id 查询
// ->find(); // 获取第一个结果
//
//// 如果找到广告主数据
// if ($userAdvertiser && $userAdvertiser->googleUser) {
// // 获取关联用户的 access_token
// return $userAdvertiser->googleUser ? $userAdvertiser->googleUser->access_token : null;
// } else {
//// return $this->errorResponse('101', '未找到该广告主或关联的用户');
// }
// }
/* @param int $customerId the customer ID
* @param $options
* @return mixed
* @throws ApiException
*/
public function runListAssetRelations(int $customerId): mixed
{
// Creates a single shared budget to be used by the campaigns added below.
$assetsResourceName = self::getAssetRelations($customerId);
// dump(json_encode($assetsResourceName));
if (is_array($assetsResourceName)) {
self::saveAssetRelations($assetsResourceName);
}
// return $assetsResourceName;
return 'insert success';
}
/* @param int $customerId the customer ID
* @param $options
* @return mixed
* @throws ApiException
*/
public function runListVideoAssetRelations(int $customerId): mixed
{
// Creates a single shared budget to be used by the campaigns added below.
$assetsResourceName = self::getVideoAssetRelations($customerId);
// dump(json_encode($assetsResourceName));
if (is_array($assetsResourceName)) {
self::saveAssetRelations($assetsResourceName);
}
// return $assetsResourceName;
return 'insert success';
}
/**
* 在数据库中保存广告素材信息
* @param $assetsResourceName
* @return void
*/
public static function saveAssetRelations($assetsResourceName)
{
$tableName = 'bps_google_ads_asset_relations';
$tableName = getenv('DB_PG_SCHEMA') ? getenv('DB_PG_SCHEMA') . '.' . $tableName : 'public' . $tableName;
foreach ($assetsResourceName as $data) {
// 修改后的插入 SQL 语句
$sql = "INSERT INTO {$tableName}
(asset_id, ad_id, ad_group_id, campaign_id, date,month,season,year, create_at, update_at)
VALUES (:asset_id, :ad_id, :ad_group_id, :campaign_id, :date,:month,:season,:year, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
ON CONFLICT (asset_id, ad_id, date)
DO NOTHING"; // 如果 (asset_id, ad_id, date) 存在,忽略插入操作
ThinkDb::execute($sql, $data);
}
}
/**
*
* @param int $customerId the customer ID
*/
public static function getAssetRelations(int $customerId)
{
$date = date('Y-m-d');
// 调用私有方法提取 year, month, season
$dateDetails = self::extractDateDetails($date);
$year = $dateDetails['year'];
$month = $dateDetails['month'];
$season = $dateDetails['season'];
// 获取所有素材
// $assets = AssetModel::where('asset_type', 4)->select(); //图片素材
$resourceNames = AssetModel::where('asset_type', 4)
->column('asset_id, resource_name');
// dump($resourceNames);return($resourceNames);
$result = [];
foreach ($resourceNames as $resourceName) {
// 获取广告表中的所有广告
$ads = ThinkDb::table('bps.bps_google_ads_ad')
// ->whereRaw("metadata->'marketing_images' @> ?", ['["customers/4060397299/assets/191677352383"]'])
// ->whereOrRaw("metadata->'square_marketing_images' @> ?", ['["customers/4060397299/assets/191677352383"]'])
->whereRaw("metadata->'marketing_images' @> ?", ['["' . $resourceName['resource_name'] . '"]'])
->whereOrRaw("metadata->'square_marketing_images' @> ?", ['["' . $resourceName['resource_name'] . '"]'])
->select();
// $ads = AdModel::where(function ($query) use ($resourceName) {
// $query->whereJsonContains('metadata->marketing_images', $resourceName)
// ->WhereOrJsonContains('metadata->square_marketing_images', $resourceName);
// })->select();
// $result[$resourceName['asset_id']] = $ads;
foreach ($ads as $ad) {
$result[$resourceName['asset_id']]['ad_id'] = $ad['ad_id'];
$result[$resourceName['asset_id']]['ad_group_id'] = $ad['ad_group_id'];
$result[$resourceName['asset_id']]['campaign_id'] = $ad['campaign_id'];
$result[$resourceName['asset_id']]['asset_id'] = $resourceName['asset_id'];
$result[$resourceName['asset_id']]['date'] = $date;
$result[$resourceName['asset_id']]['month'] = $month;
$result[$resourceName['asset_id']]['season'] = $season;
$result[$resourceName['asset_id']]['year'] = $year;
}
}
return $result;
// dump('Google Ads Asset synchronization completed.');
}
/**
*
* @param int $customerId the customer ID
*/
public static function getVideoAssetRelations(int $customerId)
{
$date = date('Y-m-d');
// 调用私有方法提取 year, month, season
$dateDetails = self::extractDateDetails($date);
$year = $dateDetails['year'];
$month = $dateDetails['month'];
$season = $dateDetails['season'];
// 获取所有素材
// $assets = AssetModel::where('asset_type', 2)->select(); //视频素材
$resourceNames = AssetModel::where('asset_type', 2)
->column('asset_id, resource_name');
// dump($resourceNames);return($resourceNames);
$result = [];
foreach ($resourceNames as $resourceName) {
// 获取广告表中的所有匹配的广告
$ads = ThinkDb::table('bps.bps_google_ads_ad')
->whereRaw("metadata->'youtube_videos' @> ?", ['["' . $resourceName['resource_name'] . '"]'])
->select();
foreach ($ads as $ad) {
$result[$resourceName['asset_id']]['ad_id'] = $ad['ad_id'];
$result[$resourceName['asset_id']]['ad_group_id'] = $ad['ad_group_id'];
$result[$resourceName['asset_id']]['campaign_id'] = $ad['campaign_id'];
$result[$resourceName['asset_id']]['asset_id'] = $resourceName['asset_id'];
$result[$resourceName['asset_id']]['date'] = $date;
$result[$resourceName['asset_id']]['month'] = $month;
$result[$resourceName['asset_id']]['season'] = $season;
$result[$resourceName['asset_id']]['year'] = $year;
}
}
return $result;
// dump('Google Ads Asset synchronization completed.');
}
/**
* 从日期字符串中提取年、月、季节信息,并返回这些信息
*
* @param string $date 日期,格式为 'Y-m-d'
* @return array 包含 year, month 和 season 的数组
*/
private static function extractDateDetails($date)
{
$dateObj = new DateTime($date); // 将日期字符串转换为 DateTime 对象
// 提取年和月
$year = (int)$dateObj->format('Y');
$month = (int)$dateObj->format('m');
// 计算季度
if ($month >= 1 && $month <= 3) {
$season = (int)$dateObj->format('Ym') . '01'; // Q1
} elseif ($month >= 4 && $month <= 6) {
$season = (int)$dateObj->format('Ym') . '02'; // Q2
} elseif ($month >= 7 && $month <= 9) {
$season = (int)$dateObj->format('Ym') . '03'; // Q3
} else {
$season = (int)$dateObj->format('Ym') . '04'; // Q4
}
return [
'year' => $year,
'month' => $month,
'season' => $season
];
}
/**
* This example updates the CPC bid and status for a given ad group. To get ad groups, run
* GetAdAds.php.
*/
/* @param int $customerId the customer ID
* @param $options
* @return mixed
* @throws ApiException
*/
public function runUpdateAd($options): mixed
{
// $googleAdsClient = $this->googleAdsClient;
$googleAdsClient = new GoogleAdsClientService($options['customer_id']);
// Creates a single shared budget to be used by the campaigns added below.
$resourceNames = self::updateAd($googleAdsClient->getGoogleAdsClient(), $options['customer_id'], $options['group_id'], $options['ad_id'], $options['status']);
return $resourceNames;
}
/**
* Runs the updateAd example.
*
* @param GoogleAdsClient $googleAdsClient the Google Ads API client
* @param int $customerId the customer ID
* @param int $adGroupId the ad group ID that the ad group ad belongs to
* @param int $adId the ID of the ad to pause
*/
public static function updateAd(
GoogleAdsClient $googleAdsClient,
int $customerId,
int $adGroupId,
int $adId,
int $status
)
{
// Creates ad group ad resource name.
$adGroupAdResourceName = ResourceNames::forAdGroupAd($customerId, $adGroupId, $adId);
// Creates an ad and sets its status to PAUSED.
$adGroupAd = new AdGroupAd();
$adGroupAd->setResourceName($adGroupAdResourceName);
// $adGroupAd->setStatus(AdGroupAdStatus::PAUSED);
$adGroupAd->setStatus($status);
// Constructs an operation that will pause the ad 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 ad group you want to change.
$adGroupAdOperation = new AdGroupAdOperation();
$adGroupAdOperation->setUpdate($adGroupAd);
$adGroupAdOperation->setUpdateMask(FieldMasks::allSetFieldsOf($adGroupAd));
// Issues a mutate request to pause the ad group ad.
$adGroupAdServiceClient = $googleAdsClient->getAdGroupAdServiceClient();
$response = $adGroupAdServiceClient->mutateAdGroupAds(MutateAdGroupAdsRequest::build(
$customerId,
[$adGroupAdOperation]
));
// Prints the resource name of the paused ad group ad.
/** @var AdGroupAd $pausedAdGroupAd */
$pausedAdGroupAd = $response->getResults()[0];
// printf(
// "Ad group ad with resource name: '%s' is paused.%s",
// $pausedAdGroupAd->getResourceName(),
// PHP_EOL
// );
return $pausedAdGroupAd->getResourceName();
}
/**
* 更新广告状态
*/
public function updateAdStatus(int $customerId, int $adGroupId, int $adId, int $status)
{
// 从数据库获取 Ad
$ad = AdModel::find($adId);
if (!$ad) {
// throw new ValidateException('Ad not found');
return false;
}
// 更新数据库中的状态
// $ad->updateStatus($status);
if ($this->modifyDbAdStatus($adId, $status)) {
// 更新 Google Ads 上的状态
// $googleAdsClient = $this->googleAdsClient;
$googleAdsClient = new GoogleAdsClientService($customerId);
$resourceName = self::updateAd($googleAdsClient->getGoogleAdsClient(), $customerId, $adGroupId, $adId, $status);
return true;
}
return false;
}
/**
* 获取广告状态
*/
public function getAdStatus(int $adId)
{
// 从数据库获取 Ad
$ad = AdModel::find($adId);
if (!$ad) {
// throw new ValidateException('Ad not found');
}
// 返回广告状态
return $ad->getStatusTextAttr(null, $ad->toArray());
}
/**
* 判断广告是否启用
*/
// public function isAdEnabled(int $adId)
// {
// $ad = Ad::find($adId);
// if (!$ad) {
// throw new ValidateException('Ad not found');
// }
//
// return $ad->isEnabled();
// }
/**
* 判断广告是否暂停
*/
// public function isAdPaused(int $adId)
// {
// $ad = Ad::find($adId);
// if (!$ad) {
// throw new ValidateException('Ad not found');
// }
//
// return $ad->isPaused();
// }
/**
* 判断广告是否停止
*/
// public function isAdStopped(int $adId)
// {
// $ad = Ad::find($adId);
// if (!$ad) {
// throw new ValidateException('Ad not found');
// }
//
// return $ad->isStopped();
// }
/**
* This example updates the CPC bid and status for a given ad group. To get ad groups, run
* GetAdAds.php.
*/
/* @param int $customerId the customer ID
* @param $options
* @return mixed
* @throws ApiException
*/
public function runGetResponsiveSearchAds($options): mixed
{
// $googleAdsClient = $this->googleAdsClient;
$googleAdsClient = new GoogleAdsClientService($options['customer_id']);
// Creates a single shared budget to be used by the campaigns added below.
if (!isset($options['group_id'])) {
$options['group_id'] = null;
}
$resourceNames = self::getResponsiveSearchAds($googleAdsClient->getGoogleAdsClient(), $options['customer_id'], $options['group_id']);
return $resourceNames;
}
/**
* 获取指定广告组中未移除的自适应搜索广告。
*
* @param GoogleAdsClient $googleAdsClient the Google Ads API client
* @param int $customerId the customer ID
* @param int|null $adGroupId the ad group ID for which responsive search ads will be retrieved.
* If `null`, returns from all ad groups
*/
public static function getResponsiveSearchAds(
GoogleAdsClient $googleAdsClient,
int $customerId,
?int $adGroupId
)
{
$googleAdsServiceClient = $googleAdsClient->getGoogleAdsServiceClient();
// Creates a query that retrieves responsive search ads.
$query =
'SELECT ad_group.id, '
. 'ad_group_ad.ad.id, '
. 'ad_group_ad.ad.responsive_search_ad.headlines, '
. 'ad_group_ad.ad.responsive_search_ad.descriptions, '
. 'ad_group_ad.status '
. 'FROM ad_group_ad '
. 'WHERE ad_group_ad.ad.type = RESPONSIVE_SEARCH_AD '
. 'AND ad_group_ad.status != "REMOVED"';
if (!is_null($adGroupId)) {
$query .= " AND ad_group.id = $adGroupId";
}
// Issues a search request.
$response =
$googleAdsServiceClient->search(SearchGoogleAdsRequest::build($customerId, $query));
// Iterates over all rows in all pages and prints the requested field values for
// the responsive search ad in each row.
$isEmptyResult = true;
$resources = [];
foreach ($response->iterateAllElements() as $googleAdsRow) {
/** @var GoogleAdsRow $googleAdsRow */
$isEmptyResult = false;
$ad = $googleAdsRow->getAdGroupAd()->getAd();
$resource = [];
// printf(
// "Responsive search ad with resource name '%s' and status '%s' was found.%s",
// $ad->getResourceName(),
// AdGroupAdStatus::name($googleAdsRow->getAdGroupAd()->getStatus()),
// PHP_EOL
// );
$resource['resource_name'] = $ad->getResourceName();
$resource['status'] = AdGroupAdStatus::name($googleAdsRow->getAdGroupAd()->getStatus());
$responsiveSearchAdInfo = $ad->getResponsiveSearchAd();
// printf(
// 'Headlines:%1$s%2$sDescriptions:%1$s%3$s%1$s',
// PHP_EOL,
// self::convertAdTextAssetsToString($responsiveSearchAdInfo->getHeadlines()),
// self::convertAdTextAssetsToString($responsiveSearchAdInfo->getDescriptions())
// )
$resource['content'] = sprintf(
'Headlines:%1$s%2$sDescriptions:%1$s%3$s%1$s',
PHP_EOL,
self::convertAdTextAssetsToString($responsiveSearchAdInfo->getHeadlines()),
self::convertAdTextAssetsToString($responsiveSearchAdInfo->getDescriptions())
);
$resources[] = $resource;
}
return $resources;
// if ($isEmptyResult) {
// print 'No responsive search ads were found.' . PHP_EOL;
// }
}
/**
* Converts the list of AdTextAsset objects into a string representation.
*
* @param RepeatedField $assets the list of AdTextAsset objects
* @return string the string representation of the provided list of AdTextAsset objects
*/
private static function convertAdTextAssetsToString(RepeatedField $assets): string
{
$result = '';
foreach ($assets as $asset) {
/** @var AdTextAsset $asset */
$result .= sprintf(
"\t%s pinned to %s.%s",
$asset->getText(),
ServedAssetFieldType::name($asset->getPinnedField()),
PHP_EOL
);
}
return $result;
}
/**
* This example updates the CPC bid and status for a given ad group. To get ad groups, run
* GetAdAds.php.
*/
/* @param int $customerId the customer ID
* @param $options
* @return mixed
* @throws ApiException
*/
public function runUpdateResponsiveSearchAd($options): mixed
{
// $googleAdsClient = $this->googleAdsClient;
$googleAdsClient = new GoogleAdsClientService($options['customer_id']);
// Creates a single shared budget to be used by the campaigns added below.
$resourceName = self::updateResponsiveSearchAd($googleAdsClient->getGoogleAdsClient(), $options['customer_id'], $options['ad_id']);
return $resourceName;
}
/**
* updateResponsiveSearchAd.
*
* @param GoogleAdsClient $googleAdsClient the Google Ads API client
* @param int $customerId the customer ID
* @param int $adId the ad ID to update
*/
// [START update_responsive_search_ad]
public static function updateResponsiveSearchAd(
GoogleAdsClient $googleAdsClient,
int $customerId,
int $adId
)
{
// Creates an ad with the specified resource name and other changes.
$ad = new Ad([
'resource_name' => ResourceNames::forAd($customerId, $adId),
'responsive_search_ad' => new ResponsiveSearchAdInfo([
// Update some properties of the responsive search ad.
'headlines' => [
new AdTextAsset([
'text' => 'Cruise to Pluto #' . Helper::getShortPrintableDatetime(),
'pinned_field' => ServedAssetFieldType::HEADLINE_1
]),
new AdTextAsset(['text' => 'Tickets on sale now', 'pinned_field' => ServedAssetFieldType::HEADLINE_2]),
new AdTextAsset(['text' => 'Buy your ticket now'])
],
'descriptions' => [
new AdTextAsset(['text' => 'Best space cruise ever.']),
new AdTextAsset([
'text' => 'The most wonderful space experience you will ever have.'])
]
]),
'final_urls' => ['http://www.baidu.com'],
'final_mobile_urls' => ['http://www.baidu.com/mobile']
]);
// Constructs an operation that will update the ad, using the FieldMasks to derive the
// update mask. This mask tells the Google Ads API which attributes of the ad you want to
// change.
$adOperation = new AdOperation();
$adOperation->setUpdate($ad);
$adOperation->setUpdateMask(FieldMasks::allSetFieldsOf($ad));
// Issues a mutate request to update the ad.
$adServiceClient = $googleAdsClient->getAdServiceClient();
$response =
$adServiceClient->mutateAds(MutateAdsRequest::build($customerId, [$adOperation]));
// Prints the resource name of the updated ad.
/** @var Ad $updatedAd */
$updatedAd = $response->getResults()[0];
printf(
"Updated ad with resource name: '%s'.%s",
$updatedAd->getResourceName(),
PHP_EOL
);
return $updatedAd->getResourceName();
}
// [END update_responsive_search_ad]
/**
* 根据给定的前缀搜索 Google Ads 字段检索到关于这些字段的元数据metadata
*/
/* @param int $customerId the customer ID
* @param $options
* @return mixed
* @throws ApiException
*/
public function runSearchForGoogleAdsFields($options): mixed
{
// $googleAdsClient = $this->googleAdsClient;
$googleAdsClient = new GoogleAdsClientService($options['customer_id']);
// Creates a single shared budget to be used by the campaigns added below.
$googleAdsFieldData = self::searchForGoogleAdsFields($googleAdsClient->getGoogleAdsClient(), $options['name_prefix']);
return $googleAdsFieldData;
}
/**
* Runs the example SearchForGoogleAdsFields.
*
* @param GoogleAdsClient $googleAdsClient the Google Ads API client
* @param string $namePrefix the name prefix to use in the query
*/
public static function searchForGoogleAdsFields(GoogleAdsClient $googleAdsClient, string $namePrefix)
{
$googleAdsFieldServiceClient = $googleAdsClient->getGoogleAdsFieldServiceClient();
// Searches for all fields whose name begins with the specified namePrefix.
// A single "%" is the wildcard token in the Google Ads Query language.
$query = "SELECT name, category, selectable, filterable, sortable, selectable_with, "
. "data_type, is_repeated WHERE name LIKE '$namePrefix%'";
$response = $googleAdsFieldServiceClient->searchGoogleAdsFields(
SearchGoogleAdsFieldsRequest::build($query)
);
if (iterator_count($response->getIterator()) === 0) {
printf(
"No GoogleAdsFields found with a name that begins with %s.%s",
$namePrefix,
PHP_EOL
);
return;
}
// Iterates over all rows and prints our the metadata of each matching GoogleAdsField.
foreach ($response->iterateAllElements() as $googleAdsField) {
/** @var GoogleAdsField $googleAdsField */
$fieldInfo = [
'name' => $googleAdsField->getName(),
'category' => GoogleAdsFieldCategory::name($googleAdsField->getCategory()),
'data_type' => GoogleAdsFieldDataType::name($googleAdsField->getDataType()),
'selectable' => $googleAdsField->getSelectable() ? 'true' : 'false',
'filterable' => $googleAdsField->getFilterable() ? 'true' : 'false',
'sortable' => $googleAdsField->getSortable() ? 'true' : 'false',
'repeated' => $googleAdsField->getIsRepeated() ? 'true' : 'false',
'selectable_with' => []
];
// Check if there are fields that are selectable with the current field
if ($googleAdsField->getSelectableWith()->count() > 0) {
$selectableWithFields = iterator_to_array($googleAdsField->getSelectableWith()->getIterator());
sort($selectableWithFields); // Sort the fields alphabetically
$fieldInfo['selectable_with'] = $selectableWithFields;
}
// Add the field info to the result array
$googleAdsFieldData[] = $fieldInfo;
//
// printf("%s:%s", $googleAdsField->getName(), PHP_EOL);
// printf(
// " %-16s: %s%s",
// "category:",
// GoogleAdsFieldCategory::name($googleAdsField->getCategory()),
// PHP_EOL
// );
// printf(
// " %-16s: %s%s",
// "data type:",
// GoogleAdsFieldDataType::name($googleAdsField->getDataType()),
// PHP_EOL
// );
// printf(
// " %-16s: %s%s",
// "selectable:",
// $googleAdsField->getSelectable() ? 'true' : 'false',
// PHP_EOL
// );
// printf(
// " %-16s: %s%s",
// "filterable:",
// $googleAdsField->getFilterable() ? 'true' : 'false',
// PHP_EOL
// );
// printf(
// " %-16s: %s%s",
// "sortable:",
// $googleAdsField->getSortable() ? 'true' : 'false',
// PHP_EOL
// );
// printf(
// " %-16s: %s%s",
// "repeated:",
// $googleAdsField->getIsRepeated() ? 'true' : 'false',
// PHP_EOL
// );
//
// if ($googleAdsField->getSelectableWith()->count() > 0) {
// // Prints the list of fields that are selectable with the field.
// $selectableWithFields =
// iterator_to_array($googleAdsField->getSelectableWith()->getIterator());
// // Sorts and then prints the list.
// sort($selectableWithFields);
// print ' selectable with:' . PHP_EOL;
// foreach ($selectableWithFields as $selectableWithField) {
// /** @var string $selectableWithField */
// printf(" $selectableWithField%s", PHP_EOL);
// }
// }
}
return $googleAdsFieldData; // Return the result array
}
}