654 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			654 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | ||
| 
 | ||
| namespace app\service;
 | ||
| 
 | ||
| 
 | ||
| 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\Lib\V18\GoogleAdsClientBuilder;
 | ||
| use Google\Ads\GoogleAds\Lib\V18\GoogleAdsException;
 | ||
| use Google\Ads\GoogleAds\Lib\OAuth2TokenBuilder;
 | ||
| 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 Google\ApiCore\ApiException;
 | ||
| 
 | ||
| class GoogleAdsAdService extends BaseService
 | ||
| {
 | ||
|     private $googleAdsClient;
 | ||
| 
 | ||
|     public function __construct()
 | ||
|     {
 | ||
|         $advertiserId = getenv('GOOGLE_ADS_CUSTOMER_ID');
 | ||
| //
 | ||
| //        // 从数据库获取 access_token
 | ||
|         $refreshToken = $this->getRefreshTokenFromDatabase($advertiserId);
 | ||
| //
 | ||
| //        if (!$refreshToken) {
 | ||
| //            throw new \Exception("Access token not found for advertiserId: " . $advertiserId);
 | ||
| //        }
 | ||
| 
 | ||
|         // OAuth2 Token Authentication
 | ||
|         $oAuth2Credential = (new OAuth2TokenBuilder())
 | ||
|             ->fromFile() // 如果需要从文件获取其他配置,可以继续使用 fromFile()
 | ||
|             ->withRefreshToken($refreshToken) // 使用动态获取的 access_token
 | ||
|             ->build();
 | ||
| 
 | ||
|         // Google Ads Client initialization
 | ||
|         $this->googleAdsClient = (new GoogleAdsClientBuilder())
 | ||
|             ->fromFile()
 | ||
|             ->withOAuth2Credential($oAuth2Credential)
 | ||
|             ->build();
 | ||
|     }
 | ||
| 
 | ||
|     // 从数据库动态获取 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 runListAds(int $customerId): mixed
 | ||
|     {
 | ||
| 
 | ||
|         $googleAdsClient = $this->googleAdsClient;
 | ||
|         // Creates a single shared budget to be used by the campaigns added below.
 | ||
|         $groupAdsResourceName = self::getAds($googleAdsClient, $customerId);
 | ||
| //        dump(json_encode($groupadsResourceName));
 | ||
|         if (is_array($groupAdsResourceName)) {
 | ||
|             self::saveAds($groupAdsResourceName);
 | ||
|         }
 | ||
| 
 | ||
|         return $groupAdsResourceName;
 | ||
|     }
 | ||
| 
 | ||
| 
 | ||
|     /**
 | ||
|      *  在数据库中保存广告系列信息
 | ||
|      * @param $groupadsResourceName
 | ||
|      * @return void
 | ||
|      */
 | ||
|     public static function saveAds($groupadsResourceName)
 | ||
|     {
 | ||
|         $tableName = 'bps_google_ads_ad';
 | ||
|         $tableName = getenv('DB_PG_SCHEMA') ? getenv('DB_PG_SCHEMA') . '.' . $tableName : 'public' . $tableName;
 | ||
|         foreach ($groupadsResourceName as $data) {
 | ||
|             $sql = "INSERT INTO  {$tableName}
 | ||
|         (ad_id, ad_group_id, customer_id, ad_name, status, resource_name)
 | ||
|             VALUES (:ad_id, :ad_group_id, :customer_id, :ad_name, :status, :resource_name)
 | ||
|             ON CONFLICT (ad_id) 
 | ||
|             DO UPDATE SET
 | ||
|                 ad_group_id = EXCLUDED.ad_group_id,
 | ||
|                 customer_id = EXCLUDED.customer_id,
 | ||
|                 ad_name = EXCLUDED.ad_name,
 | ||
|                 status = EXCLUDED.status,
 | ||
|                 resource_name = EXCLUDED.resource_name,
 | ||
|                 update_at = EXCLUDED.update_at";
 | ||
| //                        dump($sql);
 | ||
|             ThinkDb::execute($sql, $data);
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
| 
 | ||
|     /**
 | ||
|      * Runs the example.
 | ||
|      *
 | ||
|      * @param GoogleAdsClient $googleAdsClient the Google Ads API client
 | ||
|      * @param int $customerId the customer ID
 | ||
|      */
 | ||
|     // [START get_campaigns]
 | ||
| 
 | ||
|     public static function getAds(GoogleAdsClient $googleAdsClient, int $customerId)
 | ||
|     {
 | ||
|         $googleAdsServiceClient = $googleAdsClient->getGoogleAdsServiceClient();
 | ||
|         // Creates a query that retrieves all groups.
 | ||
| 
 | ||
| //            $response = $googleAdsServiceClient->search($customerId, $query);
 | ||
|         $query = "SELECT
 | ||
|                 ad_group_ad.ad.id,    
 | ||
|                 ad_group.id,
 | ||
|                 customer.id,
 | ||
|                 ad_group_ad.ad.name,                
 | ||
|                 ad_group_ad.status,                
 | ||
|                 ad_group_ad.ad.resource_name                
 | ||
|                 FROM ad_group_ad               
 | ||
|                 WHERE                
 | ||
|                 ad_group_ad.status != 'REMOVED' ";
 | ||
|         // Issues a search stream request.
 | ||
|         /** @var GoogleAdsServerStreamDecorator $stream */
 | ||
|         $stream        = $googleAdsServiceClient->searchStream(
 | ||
|             SearchGoogleAdsStreamRequest::build($customerId, $query)
 | ||
|         );
 | ||
|         $resourceNames = [];
 | ||
|         // Iterates over all rows in all messages and prints the requested field values for
 | ||
|         // the campaign in each row.
 | ||
|         foreach ($stream->iterateAllElements() as $googleAdsRow) {
 | ||
|             /** @var GoogleAdsRow $googleAdsRow */
 | ||
|             // 假设 $googleAdsRow 是从 Google Ads API 中获取的对象
 | ||
| //                $finalUrlsList = $googleAdsRow->getAdGroupAd()->getAd()->getFinalUrls();
 | ||
|             // 将最终的 URL 列表转换为 PHP 数组
 | ||
| //                $finalUrlsArray = iterator_to_array($finalUrlsList);
 | ||
|             $resourceName['ad_id']       = $googleAdsRow->getAdGroupAd()->getAd()->getId();
 | ||
|             $resourceName['ad_name']     = $googleAdsRow->getAdGroupAd()->getAd()->getName();
 | ||
|             $resourceName['ad_group_id'] = $googleAdsRow->getAdGroup()->getId();
 | ||
|             $resourceName['customer_id'] = $googleAdsRow->getCustomer()->getId();
 | ||
| //            $resourceName['final_urls']  = $finalUrlsArray;
 | ||
|             $resourceName['status']        = $googleAdsRow->getAdGroupAd()->getStatus();
 | ||
|             $resourceName['resource_name'] = $googleAdsRow->getAdGroupAd()->getAd()->getResourceName();
 | ||
|             $resourceNames[]               = $resourceName;
 | ||
|         }
 | ||
|         return $resourceNames;
 | ||
|     }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|     /**
 | ||
|      * 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;
 | ||
|         // Creates a single shared budget to be used by the campaigns added below.
 | ||
| 
 | ||
|         $resourceNames = self::updateAd($googleAdsClient, $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;
 | ||
|             $resourceName = self::updateAd($googleAdsClient,$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;
 | ||
|         // 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, $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;
 | ||
|         // Creates a single shared budget to be used by the campaigns added below.
 | ||
|         $resourceName = self::updateResponsiveSearchAd($googleAdsClient, $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;
 | ||
|         // Creates a single shared budget to be used by the campaigns added below.
 | ||
|         $googleAdsFieldData = self::searchForGoogleAdsFields($googleAdsClient, $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
 | ||
|     }
 | ||
| 
 | ||
| 
 | ||
| }
 |