Share your feedback about the AdWords API! Take our annual survey.

Campaign Management Samples

The code samples below provide examples for managing campaigns using the AdWords API. Client Library.

Add a campaign group and set its performance target

<?php
/**
 * Copyright 2017 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

namespace Google\AdsApi\Examples\AdWords\v201809\CampaignManagement;

require __DIR__ . '/../../../../vendor/autoload.php';

use Google\AdsApi\AdWords\AdWordsServices;
use Google\AdsApi\AdWords\AdWordsSession;
use Google\AdsApi\AdWords\AdWordsSessionBuilder;
use Google\AdsApi\AdWords\v201809\cm\Campaign;
use Google\AdsApi\AdWords\v201809\cm\CampaignGroup;
use Google\AdsApi\AdWords\v201809\cm\CampaignGroupOperation;
use Google\AdsApi\AdWords\v201809\cm\CampaignGroupPerformanceTarget;
use Google\AdsApi\AdWords\v201809\cm\CampaignGroupPerformanceTargetOperation;
use Google\AdsApi\AdWords\v201809\cm\CampaignGroupPerformanceTargetService;
use Google\AdsApi\AdWords\v201809\cm\CampaignGroupService;
use Google\AdsApi\AdWords\v201809\cm\CampaignOperation;
use Google\AdsApi\AdWords\v201809\cm\CampaignService;
use Google\AdsApi\AdWords\v201809\cm\EfficiencyTargetType;
use Google\AdsApi\AdWords\v201809\cm\Money;
use Google\AdsApi\AdWords\v201809\cm\Operator;
use Google\AdsApi\AdWords\v201809\cm\PerformanceTarget;
use Google\AdsApi\AdWords\v201809\cm\SpendTargetType;
use Google\AdsApi\AdWords\v201809\cm\VolumeGoalType;
use Google\AdsApi\Common\OAuth2TokenBuilder;

/**
 * This code example adds a campaign group and sets a performance target for
 * that group. To get campaigns, run GetCampaigns.php. To download reports, run
 * DownloadCriteriaReportWithAwql.php.
 */
class AddCampaignGroupsAndPerformanceTargets
{

    const CAMPAIGN_ID_1 = 'INSERT_CAMPAIGN_ID_1_HERE';
    const CAMPAIGN_ID_2 = 'INSERT_CAMPAIGN_ID_2_HERE';

    public static function runExample(
        AdWordsServices $adWordsServices,
        AdWordsSession $session,
        $campaignIds
    ) {
        $campaignGroup = self::createCampaignGroup($adWordsServices, $session);
        self::addCampaignsToGroup(
            $adWordsServices,
            $session,
            $campaignGroup,
            $campaignIds
        );
        self::createPerformanceTarget($adWordsServices, $session, $campaignGroup);
    }

    private static function createCampaignGroup(
        AdWordsServices $adWordsServices,
        AdWordsSession $session
    ) {
        $campaignGroupService = $adWordsServices->get($session, CampaignGroupService::class);

        // Create the campaign group.
        $campaignGroup = new CampaignGroup();
        $campaignGroup->setName('Mars campaign group #' . uniqid());

        // Create the operation.
        $operation = new CampaignGroupOperation();
        $operation->setOperand($campaignGroup);
        $operation->setOperator(Operator::ADD);

        $campaignGroup = $campaignGroupService->mutate([$operation])->getValue()[0];
        printf(
            "Campaign group with ID %d and name '%s' was created.\n",
            $campaignGroup->getId(),
            $campaignGroup->getName()
        );

        return $campaignGroup;
    }

    private static function addCampaignsToGroup(
        AdWordsServices $adWordsServices,
        AdWordsSession $session,
        $campaignGroup,
        $campaignIds
    ) {
        $campaignService = $adWordsServices->get($session, CampaignService::class);

        $operations = [];
        foreach ($campaignIds as $campaignId) {
            $campaign = new Campaign();
            $campaign->setId($campaignId);
            $campaign->setCampaignGroupId($campaignGroup->getId());

            $operation = new CampaignOperation();
            $operation->setOperand($campaign);
            $operation->setOperator(Operator::SET);
            $operations[] = $operation;
        }

        $campaigns = $campaignService->mutate($operations)->getValue();
        printf(
            "The following campaign IDs were added to the campaign group with ID %d:\n",
            $campaignGroup->getId()
        );
        foreach ($campaigns as $campaign) {
            printf("\t%d\n", $campaign->getId());
        }
    }

    private static function createPerformanceTarget(
        AdWordsServices $adWordsServices,
        AdWordsSession $session,
        CampaignGroup $campaignGroup
    ) {
        $campaignGroupPerformanceTargetService = $adWordsServices->get(
            $session,
            CampaignGroupPerformanceTargetService::class
        );

        // Create the performance target.
        $performanceTarget = new PerformanceTarget();
        // Keep the CPC for the campaigns < $3.
        $performanceTarget->setEfficiencyTargetType(
            EfficiencyTargetType::CPC_LESS_THAN_OR_EQUAL_TO
        );
        $performanceTarget->setEfficiencyTargetValue(3000000);

        // Keep the maximum spend under $50.
        $performanceTarget->setSpendTargetType(SpendTargetType::MAXIMUM);
        $maxSpend = new Money();
        $maxSpend->setMicroAmount(500000000);
        $performanceTarget->setSpendTarget($maxSpend);

        // Aim for at least 3000 clicks.
        $performanceTarget->setVolumeTargetValue(3000);
        $performanceTarget->setVolumeGoalType(VolumeGoalType::MAXIMIZE_CLICKS);

        // Start the performance target today, and run it for the next 90 days.
        $startDate = date('Ymd', strtotime('now'));
        $endDate = date('Ymd', strtotime('+90 day'));

        $performanceTarget->setStartDate($startDate);
        $performanceTarget->setEndDate($endDate);

        // Create the campaign group performance target.
        $campaignGroupPerformanceTarget = new CampaignGroupPerformanceTarget();
        $campaignGroupPerformanceTarget->setCampaignGroupId(
            $campaignGroup->getId()
        );
        $campaignGroupPerformanceTarget->setPerformanceTarget($performanceTarget);

        // Create the operation.
        $operation = new CampaignGroupPerformanceTargetOperation();
        $operation->setOperand($campaignGroupPerformanceTarget);
        $operation->setOperator(Operator::ADD);

        $campaignGroupPerformanceTarget = $campaignGroupPerformanceTargetService->mutate([$operation])->getValue()[0];

        // Display the results.
        printf(
            "Campaign group performance target with ID %d was added for campaign group ID %d.\n",
            $campaignGroupPerformanceTarget->getId(),
            $campaignGroupPerformanceTarget->getCampaignGroupId()
        );
    }


    public static function main()
    {
        // Generate a refreshable OAuth2 credential for authentication.
        $oAuth2Credential = (new OAuth2TokenBuilder())->fromFile()->build();

        // Construct an API session configured from a properties file and the
        // OAuth2 credentials above.
        $session = (new AdWordsSessionBuilder())->fromFile()->withOAuth2Credential($oAuth2Credential)->build();
        self::runExample(
            new AdWordsServices(),
            $session,
            [intval(self::CAMPAIGN_ID_1), intval(self::CAMPAIGN_ID_2)]
        );
    }
}

AddCampaignGroupsAndPerformanceTargets::main();

Add a label to multiple campaigns

<?php
/**
 * Copyright 2017 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

namespace Google\AdsApi\Examples\AdWords\v201809\CampaignManagement;

require __DIR__ . '/../../../../vendor/autoload.php';

use Google\AdsApi\AdWords\AdWordsServices;
use Google\AdsApi\AdWords\AdWordsSession;
use Google\AdsApi\AdWords\AdWordsSessionBuilder;
use Google\AdsApi\AdWords\v201809\cm\CampaignLabel;
use Google\AdsApi\AdWords\v201809\cm\CampaignLabelOperation;
use Google\AdsApi\AdWords\v201809\cm\CampaignService;
use Google\AdsApi\AdWords\v201809\cm\Operator;
use Google\AdsApi\Common\OAuth2TokenBuilder;

/**
 * This example adds a label to multiple campaigns.
 */
class AddCampaignLabels
{

    const CAMPAIGN_ID_1 = 'INSERT_CAMPAIGN_ID_1_HERE';
    const CAMPAIGN_ID_2 = 'INSERT_CAMPAIGN_ID_2_HERE';
    const LABEL_ID = 'INSERT_LABEL_ID_HERE';

    public static function runExample(
        AdWordsServices $adWordsServices,
        AdWordsSession $session,
        array $campaignIds,
        $labelId
    ) {
        $campaignService = $adWordsServices->get($session, CampaignService::class);

        // Create campaign labels and campaign label operations, and add the
        // operations to the list.
        $operations = [];
        foreach ($campaignIds as $campaignId) {
            $campaignLabel = new CampaignLabel();
            $campaignLabel->setCampaignId($campaignId);
            $campaignLabel->setLabelId($labelId);

            $operation = new CampaignLabelOperation();
            $operation->setOperand($campaignLabel);
            $operation->setOperator(Operator::ADD);

            $operations[] = $operation;
        }

        // Add campaign labels on the server and print out some information for
        // each created campaign label.
        $result = $campaignService->mutateLabel($operations);
        foreach ($result->getValue() as $campaignLabel) {
            printf(
                "Campaign label for campaign ID %d and label ID %d was added.\n",
                $campaignLabel->getCampaignId(),
                $campaignLabel->getLabelId()
            );
        }
    }

    public static function main()
    {
        // Generate a refreshable OAuth2 credential for authentication.
        $oAuth2Credential = (new OAuth2TokenBuilder())->fromFile()->build();

        // Construct an API session configured from a properties file and the
        // OAuth2 credentials above.
        $session = (new AdWordsSessionBuilder())->fromFile()->withOAuth2Credential($oAuth2Credential)->build();
        self::runExample(
            new AdWordsServices(),
            $session,
            [intval(self::CAMPAIGN_ID_1), intval(self::CAMPAIGN_ID_2)],
            intval(self::LABEL_ID)
        );
    }
}

AddCampaignLabels::main();

Add a campaign using BatchJobService

<?php
/**
 * Copyright 2017 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

namespace Google\AdsApi\Examples\AdWords\v201809\CampaignManagement;

require __DIR__ . '/../../../../vendor/autoload.php';

use Google\AdsApi\AdWords\AdWordsServices;
use Google\AdsApi\AdWords\AdWordsSession;
use Google\AdsApi\AdWords\AdWordsSessionBuilder;
use Google\AdsApi\AdWords\BatchJobs\v201809\BatchJobs;
use Google\AdsApi\AdWords\v201809\cm\AdGroup;
use Google\AdsApi\AdWords\v201809\cm\AdGroupAd;
use Google\AdsApi\AdWords\v201809\cm\AdGroupAdOperation;
use Google\AdsApi\AdWords\v201809\cm\AdGroupCriterionOperation;
use Google\AdsApi\AdWords\v201809\cm\AdGroupOperation;
use Google\AdsApi\AdWords\v201809\cm\AdvertisingChannelType;
use Google\AdsApi\AdWords\v201809\cm\BatchJob;
use Google\AdsApi\AdWords\v201809\cm\BatchJobOperation;
use Google\AdsApi\AdWords\v201809\cm\BatchJobService;
use Google\AdsApi\AdWords\v201809\cm\BatchJobStatus;
use Google\AdsApi\AdWords\v201809\cm\BiddableAdGroupCriterion;
use Google\AdsApi\AdWords\v201809\cm\BiddingStrategyConfiguration;
use Google\AdsApi\AdWords\v201809\cm\BiddingStrategyType;
use Google\AdsApi\AdWords\v201809\cm\Budget;
use Google\AdsApi\AdWords\v201809\cm\BudgetBudgetDeliveryMethod;
use Google\AdsApi\AdWords\v201809\cm\BudgetOperation;
use Google\AdsApi\AdWords\v201809\cm\Campaign;
use Google\AdsApi\AdWords\v201809\cm\CampaignCriterionOperation;
use Google\AdsApi\AdWords\v201809\cm\CampaignOperation;
use Google\AdsApi\AdWords\v201809\cm\CampaignStatus;
use Google\AdsApi\AdWords\v201809\cm\CpcBid;
use Google\AdsApi\AdWords\v201809\cm\ExpandedTextAd;
use Google\AdsApi\AdWords\v201809\cm\Keyword;
use Google\AdsApi\AdWords\v201809\cm\KeywordMatchType;
use Google\AdsApi\AdWords\v201809\cm\ManualCpcBiddingScheme;
use Google\AdsApi\AdWords\v201809\cm\Money;
use Google\AdsApi\AdWords\v201809\cm\NegativeCampaignCriterion;
use Google\AdsApi\AdWords\v201809\cm\Operator;
use Google\AdsApi\AdWords\v201809\cm\Predicate;
use Google\AdsApi\AdWords\v201809\cm\PredicateOperator;
use Google\AdsApi\AdWords\v201809\cm\Selector;
use Google\AdsApi\Common\OAuth2TokenBuilder;
use UnexpectedValueException;

/**
 * This example adds complete campaigns using BatchJobService.
 */
class AddCompleteCampaignsUsingBatchJob
{

    const NUMBER_OF_CAMPAIGNS_TO_ADD = 2;
    const NUMBER_OF_ADGROUPS_TO_ADD = 2;
    const NUMBER_OF_KEYWORDS_TO_ADD = 5;
    const POLL_FREQUENCY_SECONDS = 30;
    const MAX_POLL_ATTEMPTS = 60;

    private static $temporaryId = 0;

    public static function runExample(
        AdWordsServices $adWordsServices,
        AdWordsSession $session
    ) {
        $batchJobService = $adWordsServices->get($session, BatchJobService::class);

        // Create a BatchJob.
        $addOp = new BatchJobOperation();
        $addOp->setOperator(Operator::ADD);
        $addOp->setOperand(new BatchJob());

        $result = $batchJobService->mutate([$addOp]);
        $batchJob = $result->getValue()[0];

        // Get the upload URL from the new job.
        $uploadUrl = $batchJob->getUploadUrl()->getUrl();
        printf(
            "Created BatchJob with ID %d, status '%s' and upload URL '%s'.\n",
            $batchJob->getId(),
            $batchJob->getStatus(),
            $uploadUrl
        );

        $namePrefix = uniqid();
        // Create and add an operation to create a new budget.
        $budgetOperation = self::buildBudgetOperation($namePrefix);
        $operations = [$budgetOperation];

        // Create and add an operation to create new campaigns.
        $campaignOperations = self::buildCampaignOperations($namePrefix, $budgetOperation);
        $operations = array_merge($operations, $campaignOperations);

        // Create and add operations to create new negative keyword criteria for
        // each campaign.
        $campaignCriterionOperations = self::buildCampaignCriterionOperations($campaignOperations);
        $operations = array_merge($operations, $campaignCriterionOperations);

        // Create and add operations to create new ad groups.
        $adGroupOperations = self::buildAdGroupOperations($namePrefix, $campaignOperations);
        $operations = array_merge($operations, $adGroupOperations);

        // Create and add operations to create new ad group criteria (keywords).
        $adGroupCriterionOperations = self::buildAdGroupCriterionOperations($adGroupOperations);
        $operations = array_merge($operations, $adGroupCriterionOperations);

        // Create and add operations to create new ad group ads (text ads).
        $adGroupAdOperations = self::buildAdGroupAdOperations($adGroupOperations);
        $operations = array_merge($operations, $adGroupAdOperations);

        // Use BatchJobs to upload all operations.
        $batchJobs = new BatchJobs($session);
        $batchJobs->uploadBatchJobOperations($operations, $uploadUrl);

        printf(
            "Uploaded %d operations for batch job with ID %d.\n",
            count($operations),
            $batchJob->getId()
        );

        // Poll for completion of the batch job using an exponential back off.
        $pollAttempts = 0;
        $isPending = true;
        do {
            $sleepSeconds = self::POLL_FREQUENCY_SECONDS * pow(2, $pollAttempts);
            printf("Sleeping %d seconds...\n", $sleepSeconds);
            sleep($sleepSeconds);

            $selector = new Selector();
            $selector->setFields(
                ['Id', 'Status', 'DownloadUrl', 'ProcessingErrors', 'ProgressStats']
            );
            $selector->setPredicates(
                [
                    new Predicate('Id', PredicateOperator::EQUALS, [$batchJob->getId()])
                ]
            );
            $batchJob = $batchJobService->get($selector)->getEntries()[0];
            printf(
                "Batch job ID %d has status '%s'.\n",
                $batchJob->getId(),
                $batchJob->getStatus()
            );

            $pollAttempts++;
            if ($batchJob->getStatus() !== BatchJobStatus::ACTIVE
                && $batchJob->getStatus() !== BatchJobStatus::AWAITING_FILE
                && $batchJob->getStatus() !== BatchJobStatus::CANCELING) {
                $isPending = false;
            }
        } while ($isPending && $pollAttempts <= self::MAX_POLL_ATTEMPTS);

        if ($isPending) {
            throw new UnexpectedValueException(
                sprintf(
                    'Job is still pending state after polling %d times.',
                    self::MAX_POLL_ATTEMPTS
                )
            );
        }

        if ($batchJob->getProcessingErrors() !== null) {
            $i = 0;
            foreach ($batchJob->getProcessingErrors() as $processingError) {
                printf(
                    " Processing error [%d]: errorType=%s, trigger=%s, errorString=%s, fieldPath=%s, reason=%s\n",
                    $i++,
                    $processingError->getApiErrorType(),
                    $processingError->getTrigger(),
                    $processingError->getErrorString(),
                    $processingError->getFieldPath(),
                    $processingError->getReason()
                );
            }
        } else {
            printf("No processing errors found.\n");
        }

        if ($batchJob->getDownloadUrl() !== null
            && $batchJob->getDownloadUrl()->getUrl() !== null) {
            $mutateResults = $batchJobs->downloadBatchJobResults(
                $batchJob->getDownloadUrl()->getUrl()
            );
            printf(
                "Downloaded results from %s:\n",
                $batchJob->getDownloadUrl()->getUrl()
            );

            if (count($mutateResults) === 0) {
                printf("  No results available.\n");
            } else {
                foreach ($mutateResults as $mutateResult) {
                    $outcome = $mutateResult->getErrorList() === null ? 'SUCCESS' : 'FAILURE';
                    printf(
                        "  Operation [%d] - %s\n",
                        $mutateResult->getIndex(),
                        $outcome
                    );
                }
            }
        } else {
            printf("No results available for download.\n");
        }
    }

    /**
     * Builds objects of AdGroupAdOperation for creating an ad group ad for
     * ad groups in the specified ad group operations.
     *
     * @param AdGroupOperation[] $adGroupOperations an array of AdGroupOperation
     * @return array an array of AdGroupAdOperation
     */
    private static function buildAdGroupAdOperations(array $adGroupOperations)
    {
        $operations = [];
        foreach ($adGroupOperations as $adGroupOperation) {
            $adGroupId = $adGroupOperation->getOperand()->getId();
            $adGroupAd = new AdGroupAd();
            $adGroupAd->setAdGroupId($adGroupId);

            $expandedTextAd = new ExpandedTextAd();
            $expandedTextAd->setHeadlinePart1('Luxury Cruise to Mars');
            $expandedTextAd->setHeadlinePart2('Visit the Red Planet in style.');
            $expandedTextAd->setDescription('Low-gravity fun for everyone!');
            $expandedTextAd->setFinalUrls(['http://www.example.com/1']);

            $adGroupAd->setAd($expandedTextAd);

            $operation = new AdGroupAdOperation();
            $operation->setOperator(Operator::ADD);
            $operation->setOperand($adGroupAd);

            $operations[] = $operation;
        }

        return $operations;
    }

    /**
     * Builds objects of AdGroupCriterionOperation for creating biddable criteria
     * (as keywords) for ad groups in the specified ad group operations. 50% of
     * keywords are created with some invalid characters to demonstrate how
     * BatchJobService returns information about such errors.
     *
     * @param AdGroupOperation[] $adGroupOperations an array of AdGroupOperation
     * @return array an array of AdGroupCriterionOperation
     */
    private static function buildAdGroupCriterionOperations(array $adGroupOperations)
    {
        $adGroupCriteriaOperations = [];

        // Create AdGroupCriterionOperations to add keywords.
        foreach ($adGroupOperations as $adGroupOperation) {
            $newAdGroupId = $adGroupOperation->getOperand()->getId();
            for ($i = 0; $i < self::NUMBER_OF_KEYWORDS_TO_ADD; $i++) {
                // Create Keyword.
                $text = sprintf('mars%d', $i);

                // Make 50% of keywords invalid to demonstrate error handling.
                if ($i % 2 == 0) {
                    $text = $text . '!!!';
                }
                $keyword = new Keyword();
                $keyword->setText($text);
                $keyword->setMatchType(KeywordMatchType::BROAD);

                // Create BiddableAdGroupCriterion.
                $biddableAdGroupCriterion = new BiddableAdGroupCriterion();
                $biddableAdGroupCriterion->setAdGroupId($newAdGroupId);
                $biddableAdGroupCriterion->setCriterion($keyword);

                // Create AdGroupCriterionOperation.
                $operation = new AdGroupCriterionOperation();
                $operation->setOperand($biddableAdGroupCriterion);
                $operation->setOperator(Operator::ADD);

                // Add to list.
                $adGroupCriteriaOperations[] = $operation;
            }
        }

        return $adGroupCriteriaOperations;
    }

    /**
     * Builds objects of AdGroupOperation for creating ad groups for campaigns in
     * the specified campaign operations.
     *
     * @param string $namePrefix a prefix string used to name ad groups
     * @param CampaignOperation[] $campaignOperations an array of
     *     CampaignOperation
     * @return array an array of AdGroupOperation
     */
    private static function buildAdGroupOperations(
        $namePrefix,
        array $campaignOperations
    ) {
        $operations = [];
        foreach ($campaignOperations as $campaignOperation) {
            for ($i = 0; $i < self::NUMBER_OF_ADGROUPS_TO_ADD; $i++) {
                $adGroup = new AdGroup();
                $adGroup->setCampaignId($campaignOperation->getOperand()->getId());
                $adGroup->setId(--self::$temporaryId);
                $adGroup->setName(
                    sprintf(
                        'Batch Ad Group %s.%s',
                        $namePrefix,
                        strval($adGroup->getId())
                    )
                );

                $biddingStrategyConfiguration = new BiddingStrategyConfiguration();
                $money = new Money();
                $money->setMicroAmount(10000000);
                $bid = new CpcBid();
                $bid->setBid($money);
                $biddingStrategyConfiguration->setBids([$bid]);

                $adGroup->setBiddingStrategyConfiguration(
                    $biddingStrategyConfiguration
                );

                $operation = new AdGroupOperation();
                $operation->setOperand($adGroup);
                $operation->setOperator(Operator::ADD);

                $operations[] = $operation;
            }
        }

        return $operations;
    }

    /**
     * Builds objects of CampaignCriterionOperation for creating a negative
     * campaign criterion (as keyword) for campaigns in the specified campaign
     * operations.
     *
     * @param CampaignOperation[] $campaignOperations an array of
     *     CampaignOperation
     * @return array an array of CampaignCriterionOperation
     */
    private static function buildCampaignCriterionOperations(
        array $campaignOperations
    ) {
        $operations = [];
        foreach ($campaignOperations as $campaignOperation) {
            $keyword = new Keyword();
            $keyword->setMatchType(KeywordMatchType::BROAD);
            $keyword->setText('venus');

            $negativeCriterion = new NegativeCampaignCriterion();
            $negativeCriterion->setCampaignId(
                $campaignOperation->getOperand()->getId()
            );
            $negativeCriterion->setCriterion($keyword);

            $operation = new CampaignCriterionOperation();
            $operation->setOperand($negativeCriterion);
            $operation->setOperator(Operator::ADD);

            $operations[] = $operation;
        }

        return $operations;
    }

    /**
     * Builds objects of CampaignOperation for creating a campaign using the ID of
     * budget in the specified budget operation.
     *
     * @param string $namePrefix a prefix string used to name campaigns
     * @param BudgetOperation $budgetOperation an object of BudgetOperation
     * @return array an array of CampaignOperation
     */
    private static function buildCampaignOperations(
        $namePrefix,
        BudgetOperation $budgetOperation
    ) {
        $budgetId = $budgetOperation->getOperand()->getBudgetId();

        $operations = [];
        for ($i = 0; $i < self::NUMBER_OF_CAMPAIGNS_TO_ADD; $i++) {
            $campaign = new Campaign();
            $campaign->setId(--self::$temporaryId);
            $campaign->setName(
                sprintf(
                    'Batch Campaign %s.%s',
                    $namePrefix,
                    strval($campaign->getId())
                )
            );

            // Recommendation: Set the campaign to PAUSED when creating it to stop
            // the ads from immediately serving. Set to ENABLED once you've added
            // targeting and the ads are ready to serve.
            $campaign->setStatus(CampaignStatus::PAUSED);
            $campaign->setAdvertisingChannelType(AdvertisingChannelType::SEARCH);

            $budget = new Budget();
            $budget->setBudgetId($budgetId);
            $campaign->setBudget($budget);
            $biddingStrategyConfiguration = new BiddingStrategyConfiguration();
            $biddingStrategyConfiguration->setBiddingStrategyType(
                BiddingStrategyType::MANUAL_CPC
            );

            // You can optionally provide a bidding scheme in place of the type.
            $cpcBiddingScheme = new ManualCpcBiddingScheme();
            $biddingStrategyConfiguration->setBiddingScheme($cpcBiddingScheme);

            $campaign->setBiddingStrategyConfiguration($biddingStrategyConfiguration);

            $operation = new CampaignOperation();
            $operation->setOperand($campaign);
            $operation->setOperator(Operator::ADD);
            $operations[] = $operation;
        }

        return $operations;
    }

    /**
     * Builds BudgetOperation for creating a budget.
     *
     * @param string $namePrefix a prefix string used to name a budget
     * @return BudgetOperation an object of BudgetOperation
     */
    private static function buildBudgetOperation($namePrefix)
    {
        $budget = new Budget();
        $budget->setBudgetId(--self::$temporaryId);
        $budget->setName('Interplanetary Cruise #' . $namePrefix);
        $budgetAmount = new Money();
        $budgetAmount->setMicroAmount(50000000);
        $budget->setAmount($budgetAmount);
        $budget->setDeliveryMethod(BudgetBudgetDeliveryMethod::STANDARD);

        $budgetOperation = new BudgetOperation();
        $budgetOperation->setOperand($budget);
        $budgetOperation->setOperator(Operator::ADD);

        return $budgetOperation;
    }

    public static function main()
    {
        // Generate a refreshable OAuth2 credential for authentication.
        $oAuth2Credential = (new OAuth2TokenBuilder())->fromFile()->build();

        // Construct an API session configured from a properties file and the
        // OAuth2 credentials above.
        $session = (new AdWordsSessionBuilder())->fromFile()->withOAuth2Credential($oAuth2Credential)->build();
        self::runExample(new AdWordsServices(), $session);
    }
}

AddCompleteCampaignsUsingBatchJob::main();

Create a draft and access its campaign

<?php
/**
 * Copyright 2017 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

namespace Google\AdsApi\Examples\AdWords\v201809\CampaignManagement;

require __DIR__ . '/../../../../vendor/autoload.php';

use Google\AdsApi\AdWords\AdWordsServices;
use Google\AdsApi\AdWords\AdWordsSession;
use Google\AdsApi\AdWords\AdWordsSessionBuilder;
use Google\AdsApi\AdWords\v201809\cm\CampaignCriterion;
use Google\AdsApi\AdWords\v201809\cm\CampaignCriterionOperation;
use Google\AdsApi\AdWords\v201809\cm\CampaignCriterionService;
use Google\AdsApi\AdWords\v201809\cm\Draft;
use Google\AdsApi\AdWords\v201809\cm\DraftOperation;
use Google\AdsApi\AdWords\v201809\cm\DraftService;
use Google\AdsApi\AdWords\v201809\cm\Language;
use Google\AdsApi\AdWords\v201809\cm\Operator;
use Google\AdsApi\Common\OAuth2TokenBuilder;

/**
 * This example shows how to create a draft and access its associated
 * draft campaign.
 */
class AddDraft
{

    const BASE_CAMPAIGN_ID = 'INSERT_BASE_CAMPAIGN_ID_HERE';

    public static function runExample(
        AdWordsServices $adWordsServices,
        AdWordsSession $session,
        $baseCampaignId
    ) {
        $draftService = $adWordsServices->get($session, DraftService::class);

        $operations = [];
        // Create a draft.
        $draft = new Draft();
        $draft->setBaseCampaignId($baseCampaignId);
        $draft->setDraftname('Test Draft #' . uniqid());

        // Create a draft operation and add it to the operations list.
        $operation = new DraftOperation();
        $operation->setOperand($draft);
        $operation->setOperator(Operator::ADD);
        $operations[] = $operation;

        // Create the draft on the server and print out some information for
        // the created draft.
        $result = $draftService->mutate($operations);
        $draft = $result->getValue()[0];
        printf(
            "Draft with ID %d, base campaign ID %d, and draft campaign ID %d was added.\n",
            $draft->getDraftId(),
            $draft->getBaseCampaignId(),
            $draft->getDraftCampaignId()
        );

        // Once the draft is created, you can modify the draft campaign as if it
        // were a real campaign. For example, you may add criteria, adjust bids, or
        // even include additional ads. Adding a criterion is shown here.
        $campaignCriterionService = $adWordsServices->get($session, CampaignCriterionService::class);

        // Create a criterion.
        $language = new Language();
        $language->setId(1003); // Spanish
        $campaignCriterion = new CampaignCriterion();
        $campaignCriterion->setCampaignId($draft->getDraftCampaignId());
        $campaignCriterion->setCriterion($language);

        // Create a campaign criterion operation and add it to the operations list.
        $operations = [];
        $operation = new CampaignCriterionOperation();
        $operation->setOperand($campaignCriterion);
        $operation->setOperator(Operator::ADD);
        $operations[] = $operation;

        // Create a campaign criterion on the server.
        $campaignCriterionService->mutate($operations);

        printf(
            "Draft updated to include criteria in the campaign with ID %d.\n",
            $draft->getDraftCampaignId()
        );
    }

    public static function main()
    {
        // Generate a refreshable OAuth2 credential for authentication.
        $oAuth2Credential = (new OAuth2TokenBuilder())->fromFile()->build();

        // Construct an API session configured from a properties file and the
        // OAuth2 credentials above.
        $session = (new AdWordsSessionBuilder())->fromFile()->withOAuth2Credential($oAuth2Credential)->build();
        self::runExample(
            new AdWordsServices(),
            $session,
            intval(self::BASE_CAMPAIGN_ID)
        );
    }
}

AddDraft::main();

Upload keywords incrementally using BatchJobService

<?php
/**
 * Copyright 2017 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

namespace Google\AdsApi\Examples\AdWords\v201809\CampaignManagement;

require __DIR__ . '/../../../../vendor/autoload.php';

use Google\AdsApi\AdWords\AdWordsServices;
use Google\AdsApi\AdWords\AdWordsSession;
use Google\AdsApi\AdWords\AdWordsSessionBuilder;
use Google\AdsApi\AdWords\BatchJobs\BatchJobUploadStatus;
use Google\AdsApi\AdWords\BatchJobs\v201809\BatchJobs;
use Google\AdsApi\AdWords\v201809\cm\AdGroupCriterionOperation;
use Google\AdsApi\AdWords\v201809\cm\ApiException;
use Google\AdsApi\AdWords\v201809\cm\BatchJob;
use Google\AdsApi\AdWords\v201809\cm\BatchJobError;
use Google\AdsApi\AdWords\v201809\cm\BatchJobErrorReason;
use Google\AdsApi\AdWords\v201809\cm\BatchJobOperation;
use Google\AdsApi\AdWords\v201809\cm\BatchJobService;
use Google\AdsApi\AdWords\v201809\cm\BatchJobStatus;
use Google\AdsApi\AdWords\v201809\cm\BiddableAdGroupCriterion;
use Google\AdsApi\AdWords\v201809\cm\Keyword;
use Google\AdsApi\AdWords\v201809\cm\KeywordMatchType;
use Google\AdsApi\AdWords\v201809\cm\Operator;
use Google\AdsApi\AdWords\v201809\cm\Predicate;
use Google\AdsApi\AdWords\v201809\cm\PredicateOperator;
use Google\AdsApi\AdWords\v201809\cm\Selector;
use Google\AdsApi\Common\OAuth2TokenBuilder;
use UnexpectedValueException;

/**
 * This code sample illustrates how to perform multiple requests using the
 * BatchJobService using incremental uploads.
 */
class AddKeywordsUsingIncrementalBatchJob
{

    const NUMBER_OF_KEYWORDS_TO_ADD = 100;
    const POLL_FREQUENCY_SECONDS = 30;
    const MAX_POLL_ATTEMPTS = 5;

    const AD_GROUP_ID = 'INSERT_AD_GROUP_ID_HERE';

    public static function runExample(
        AdWordsServices $adWordsServices,
        AdWordsSession $session,
        $adGroupId
    ) {
        $batchJobService = $adWordsServices->get($session, BatchJobService::class);

        // Create a BatchJob.
        $addOp = new BatchJobOperation();
        $addOp->setOperator(Operator::ADD);
        $addOp->setOperand(new BatchJob());

        $result = $batchJobService->mutate([$addOp]);
        $batchJob = $result->getValue()[0];

        // Get the upload URL from the new job.
        $uploadUrl = $batchJob->getUploadUrl()->getUrl();
        printf(
            "Created BatchJob with ID %d, status '%s' and upload URL '%s'.\n",
            $batchJob->getId(),
            $batchJob->getStatus(),
            $uploadUrl
        );

        // Use BatchJobs to upload all operations.
        $batchJobs = new BatchJobs($session);

        // Generate and upload the first set of operations.
        $adGroupCriterionOperations = self::buildAdGroupCriterionOperations($adGroupId);
        $batchJobUploadStatus = $batchJobs->uploadIncrementalBatchJobOperations(
            $adGroupCriterionOperations,
            new BatchJobUploadStatus($uploadUrl, $session)
        );
        printf(
            "Uploaded %d operations for batch job with ID %d.\n",
            count($adGroupCriterionOperations),
            $batchJob->getId()
        );

        // Generate and upload the second set of operations.
        $adGroupCriterionOperations = self::buildAdGroupCriterionOperations($adGroupId);
        $batchJobUploadStatus = $batchJobs->uploadIncrementalBatchJobOperations(
            $adGroupCriterionOperations,
            $batchJobUploadStatus
        );
        printf(
            "Uploaded %d operations for batch job with ID %d.\n",
            count($adGroupCriterionOperations),
            $batchJob->getId()
        );

        // Generate and upload the third and final set of operations.
        $adGroupCriterionOperations = self::buildAdGroupCriterionOperations($adGroupId);
        $batchJobUploadStatus = $batchJobs->uploadIncrementalBatchJobOperations(
            $adGroupCriterionOperations,
            $batchJobUploadStatus
        );
        printf(
            "Uploaded %d operations for batch job with ID %d.\n",
            count($adGroupCriterionOperations),
            $batchJob->getId()
        );
        $batchJobs->closeIncrementalUpload($batchJobUploadStatus);

        // Poll for completion of the batch job using an exponential back off.
        $pollAttempts = 0;
        $isPending = true;
        $wasCancelRequested = false;

        $selector = new Selector();
        $selector->setFields(
            ['Id', 'Status', 'DownloadUrl', 'ProcessingErrors', 'ProgressStats']
        );
        $selector->setPredicates(
            [
                new Predicate('Id', PredicateOperator::EQUALS, [$batchJob->getId()])
            ]
        );
        do {
            $sleepSeconds = self::POLL_FREQUENCY_SECONDS * pow(2, $pollAttempts);
            printf("Sleeping %d seconds...\n", $sleepSeconds);
            sleep($sleepSeconds);

            $batchJob = $batchJobService->get($selector)->getEntries()[0];
            printf(
                "Batch job ID %d has status '%s'.\n",
                $batchJob->getId(),
                $batchJob->getStatus()
            );

            $pollAttempts++;
            if ($batchJob->getStatus() !== BatchJobStatus::ACTIVE
                && $batchJob->getStatus() !== BatchJobStatus::AWAITING_FILE
                && $batchJob->getStatus() !== BatchJobStatus::CANCELING) {
                $isPending = false;
            }

            // Optional: Cancel the job if it has not completed after polling
            // MAX_POLL_ATTEMPTS times.
            if ($isPending && !$wasCancelRequested
                && $pollAttempts === self::MAX_POLL_ATTEMPTS) {
                $batchJob->setStatus(BatchJobStatus::CANCELING);
                $batchJobSetOperation = new BatchJobOperation();
                $batchJobSetOperation->setOperand($batchJob);
                $batchJobSetOperation->setOperator(Operator::SET);

                // Only request cancellation once per job.
                $wasCancelRequested = true;
                try {
                    $batchJob = $batchJobService->mutate([$batchJobSetOperation])->getValue()[0];
                    printf(
                        "Requested cancellation of batch job with ID %d.\n",
                        $batchJob->getId()
                    );
                    // Reset the poll attempt counter to wait for cancellation.
                    $pollAttempts = 0;
                } catch (ApiException $e) {
                    $errors = $e->getErrors();
                    if ($errors !== null
                        && count($errors) > 0
                        && $errors[0] instanceof BatchJobError) {
                        $batchJobError = $errors[0];
                        if ($batchJobError->getReason() === BatchJobErrorReason::INVALID_STATE_CHANGE) {
                            printf(
                                "Attempt to cancel batch job with ID %d was rejected because"
                                . " the job already completed or was canceled.\n",
                                $batchJob->getId()
                            );
                            continue;
                        }
                    }
                    throw $e;
                } finally {
                    // Reset the poll attempt counter to wait for cancellation.
                    $pollAttempts = 0;
                }
            }
        } while ($isPending && $pollAttempts <= self::MAX_POLL_ATTEMPTS);

        if ($isPending) {
            throw new UnexpectedValueException(
                sprintf(
                    'Job is still pending state after polling %d times.',
                    self::MAX_POLL_ATTEMPTS
                )
            );
        }

        if ($batchJob->getProcessingErrors() !== null) {
            $i = 0;
            foreach ($batchJob->getProcessingErrors() as $processingError) {
                printf(
                    " Processing error [%d]: errorType=%s, trigger=%s, errorString=%s, fieldPath=%s, reason=%s\n",
                    $i++,
                    $processingError->getApiErrorType(),
                    $processingError->getTrigger(),
                    $processingError->getErrorString(),
                    $processingError->getFieldPath(),
                    $processingError->getReason()
                );
            }
        } else {
            printf("No processing errors found.\n");
        }

        if ($batchJob->getDownloadUrl() !== null
            && $batchJob->getDownloadUrl()->getUrl() !== null) {
            $mutateResults = $batchJobs->downloadBatchJobResults(
                $batchJob->getDownloadUrl()->getUrl()
            );
            printf(
                "Downloaded results from %s:\n",
                $batchJob->getDownloadUrl()->getUrl()
            );

            if (count($mutateResults) === 0) {
                printf("  No results available.\n");
            } else {
                foreach ($mutateResults as $mutateResult) {
                    $outcome = $mutateResult->getErrorList() === null ? 'SUCCESS' : 'FAILURE';
                    printf(
                        "  Operation [%d] - %s\n",
                        $mutateResult->getIndex(),
                        $outcome
                    );
                }
            }
        } else {
            printf("No results available for download.\n");
        }
    }

    /**
     * Builds objects of AdGroupCriterionOperation for creating biddable criteria
     * (as keywords) for ad groups with the specified ID. 10% of keywords are
     * created with some invalid characters to demonstrate how `BatchJobService`
     * returns information about such errors.
     *
     * @param string $adGroupId the ID of the ad group to add the keywords to
     * @return array an array of AdGroupCriterionOperation
     */
    private static function buildAdGroupCriterionOperations($adGroupId)
    {
        $adGroupCriteriaOperations = [];

        $suffix = uniqid();
        // Create AdGroupCriterionOperations to add keywords.
        for ($i = 0; $i < self::NUMBER_OF_KEYWORDS_TO_ADD; $i++) {
            // Create Keyword.
            $text = sprintf("mars%s-%d", $suffix, $i);

            // Make 10% of keywords invalid to demonstrate error handling.
            if ($i % 10 === 0) {
                $text = $text . '!!!';
            }
            $keyword = new Keyword();
            $keyword->setText($text);
            $keyword->setMatchType(KeywordMatchType::BROAD);

            // Create BiddableAdGroupCriterion.
            $biddableAdGroupCriterion = new BiddableAdGroupCriterion();
            $biddableAdGroupCriterion->setAdGroupId($adGroupId);
            $biddableAdGroupCriterion->setCriterion($keyword);

            // Create AdGroupCriterionOperation.
            $operation = new AdGroupCriterionOperation();
            $operation->setOperand($biddableAdGroupCriterion);
            $operation->setOperator(Operator::ADD);

            // Add to list.
            $adGroupCriteriaOperations[] = $operation;
        }

        return $adGroupCriteriaOperations;
    }

    public static function main()
    {
        // Generate a refreshable OAuth2 credential for authentication.
        $oAuth2Credential = (new OAuth2TokenBuilder())->fromFile()->build();

        // Construct an API session configured from a properties file and the
        // OAuth2 credentials above.
        $session = (new AdWordsSessionBuilder())->fromFile()->withOAuth2Credential($oAuth2Credential)->build();
        self::runExample(
            new AdWordsServices(),
            $session,
            intval(self::AD_GROUP_ID)
        );
    }
}

AddKeywordsUsingIncrementalBatchJob::main();

Create a trial

<?php
/**
 * Copyright 2017 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

namespace Google\AdsApi\Examples\AdWords\v201809\CampaignManagement;

require __DIR__ . '/../../../../vendor/autoload.php';

use Google\AdsApi\AdWords\AdWordsServices;
use Google\AdsApi\AdWords\AdWordsSession;
use Google\AdsApi\AdWords\AdWordsSessionBuilder;
use Google\AdsApi\AdWords\v201809\cm\CampaignTrialTrafficSplitType;
use Google\AdsApi\AdWords\v201809\cm\Operator;
use Google\AdsApi\AdWords\v201809\cm\Predicate;
use Google\AdsApi\AdWords\v201809\cm\PredicateOperator;
use Google\AdsApi\AdWords\v201809\cm\Selector;
use Google\AdsApi\AdWords\v201809\cm\Trial;
use Google\AdsApi\AdWords\v201809\cm\TrialAsyncErrorService;
use Google\AdsApi\AdWords\v201809\cm\TrialOperation;
use Google\AdsApi\AdWords\v201809\cm\TrialService;
use Google\AdsApi\AdWords\v201809\cm\TrialStatus;
use Google\AdsApi\Common\OAuth2TokenBuilder;

/**
 * This example shows how to create a trial and wait for it to complete.
 * See the Campaign Drafts and Experiments guide for more information:
 * https://developers.google.com/adwords/api/docs/guides/campaign-drafts-experiments
 */
class AddTrial
{

    const MAX_POLL_ATTEMPTS = 5;
    const POLL_FREQUENCY_SECONDS = 30;

    const DRAFT_ID = 'INSERT_DRAFT_ID_HERE';
    const BASE_CAMPAIGN_ID = 'INSERT_BASE_CAMPAIGN_ID_HERE';

    public static function runExample(
        AdWordsServices $adWordsServices,
        AdWordsSession $session,
        $draftId,
        $baseCampaignId
    ) {
        $trialService = $adWordsServices->get($session, TrialService::class);
        $trialAsynErrorService = $adWordsServices->get($session, TrialAsyncErrorService::class);

        // Create a trial.
        $trial = new Trial();
        $trial->setDraftId($draftId);
        $trial->setBaseCampaignId($baseCampaignId);
        $trial->setName('Test Trial #' . uniqid());
        $trial->setTrafficSplitPercent(50);
        $trial->setTrafficSplitType(
            CampaignTrialTrafficSplitType::RANDOM_QUERY
        );

        // Create a trial operation and add it to the operations list.
        $operations = [];
        $operation = new TrialOperation();
        $operation->setOperand($trial);
        $operation->setOperator(Operator::ADD);
        $operations[] = $operation;

        // Create the trial on the server.
        $trial = $trialService->mutate($operations)->getValue()[0];

        $selector = new Selector();
        $selector->setFields(
            ['Id', 'Status', 'BaseCampaignId', 'TrialCampaignId']
        );
        $selector->setPredicates(
            [new Predicate('Id', PredicateOperator::IN, [$trial->getId()])]
        );

        // Since creating a trial is asynchronous, we have to poll it to wait for it
        // to finish.
        $pollAttempts = 0;
        $isPending = true;
        $trial = null;
        do {
            $sleepSeconds = self::POLL_FREQUENCY_SECONDS * pow(2, $pollAttempts);
            printf("Sleeping %d seconds...\n", $sleepSeconds);
            sleep($sleepSeconds);

            $trial = $trialService->get($selector)->getEntries()[0];
            printf(
                "Trial ID %d has status '%s'.\n",
                $trial->getId(),
                $trial->getStatus()
            );

            $pollAttempts++;
            $isPending = ($trial->getStatus() === TrialStatus::CREATING) ? true : false;
        } while ($isPending && $pollAttempts <= self::MAX_POLL_ATTEMPTS);

        if ($trial->getStatus() === TrialStatus::ACTIVE) {
            // The trial creation was successful.
            printf(
                "Trial created with ID %d and trial campaign ID %d\n",
                $trial->getId(),
                $trial->getTrialCampaignId()
            );
        } elseif ($trial->getStatus() === TrialStatus::CREATION_FAILED) {
            // The trial creation failed, and errors can be fetched from the
            // TrialAsyncErrorService.
            $selector = new Selector();
            $selector->setFields(['TrialId', 'AsyncError']);
            $selector->setPredicates(
                [new Predicate('TrialId', PredicateOperator::IN, [$trial->getId()])]
            );

            $errors = $trialAsynErrorService->get($selector)->getEntries();

            if (count($errors) === 0) {
                printf(
                    "Could not retrieve errors for the trial with ID %d\n",
                    $trial->getId()
                );
            } else {
                printf("Could not create trial due to the following errors:\n");
                $i = 0;
                foreach ($errors as $error) {
                    printf("Error #%d: %s\n", $i++, $error->getAsyncError());
                }
            }
        } else {
            // Most likely, the trial is still being created. You can continue
            // polling, but we have limited the number of attempts in the example.
            printf(
                "Timed out waiting to create trial from draft with ID %d with base campaign with ID %d\n",
                $draftId,
                $baseCampaignId
            );
        }
    }

    public static function main()
    {
        // Generate a refreshable OAuth2 credential for authentication.
        $oAuth2Credential = (new OAuth2TokenBuilder())->fromFile()->build();

        // Construct an API session configured from a properties file and the
        // OAuth2 credentials above.
        $session = (new AdWordsSessionBuilder())->fromFile()->withOAuth2Credential($oAuth2Credential)->build();
        self::runExample(
            new AdWordsServices(),
            $session,
            intval(self::DRAFT_ID),
            intval(self::BASE_CAMPAIGN_ID)
        );
    }
}

AddTrial::main();

Get all disapproved ads in an ad group

<?php
/**
 * Copyright 2017 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

namespace Google\AdsApi\Examples\AdWords\v201809\CampaignManagement;

require __DIR__ . '/../../../../vendor/autoload.php';

use Google\AdsApi\AdWords\AdWordsServices;
use Google\AdsApi\AdWords\AdWordsSession;
use Google\AdsApi\AdWords\AdWordsSessionBuilder;
use Google\AdsApi\AdWords\v201809\cm\AdGroupAdService;
use Google\AdsApi\AdWords\v201809\cm\OrderBy;
use Google\AdsApi\AdWords\v201809\cm\Paging;
use Google\AdsApi\AdWords\v201809\cm\PolicyApprovalStatus;
use Google\AdsApi\AdWords\v201809\cm\Predicate;
use Google\AdsApi\AdWords\v201809\cm\PredicateOperator;
use Google\AdsApi\AdWords\v201809\cm\Selector;
use Google\AdsApi\AdWords\v201809\cm\SortOrder;
use Google\AdsApi\Common\OAuth2TokenBuilder;

/**
 * This example gets all disapproved ads in an ad group. To get ad groups, run
 * BasicOperation/GetAdGroups.php.
 */
class GetAllDisapprovedAds
{

    const AD_GROUP_ID = 'INSERT_AD_GROUP_ID_HERE';
    const PAGE_LIMIT = 500;

    public static function runExample(
        AdWordsServices $adWordsServices,
        AdWordsSession $session,
        $adGroupId
    ) {
        $adGroupAdService = $adWordsServices->get($session, AdGroupAdService::class);

        // Create a selector to select all ads for the specified ad group.
        $selector = new Selector();
        $selector->setFields(['Id', 'PolicySummary']);
        $selector->setOrdering([new OrderBy('Id', SortOrder::ASCENDING)]);
        // Create the predicate to get only disapproved ads.
        $selector->setPredicates(
            [
                new Predicate('AdGroupId', PredicateOperator::IN, [$adGroupId]),
                new Predicate(
                    'CombinedApprovalStatus',
                    PredicateOperator::EQUALS,
                    [PolicyApprovalStatus::DISAPPROVED]
                )
            ]
        );
        $selector->setPaging(new Paging(0, self::PAGE_LIMIT));

        $totalNumEntries = 0;
        $disapprovedAdsCount = 0;
        do {
            // Retrieve ad group ads one page at a time, continuing to request pages
            // until all ad group ads have been retrieved.
            $page = $adGroupAdService->get($selector);

            // Print out some information for each ad group ad.
            if ($page->getEntries() !== null) {
                $totalNumEntries = $page->getTotalNumEntries();
                foreach ($page->getEntries() as $adGroupAd) {
                    $disapprovedAdsCount++;
                    $policySummary = $adGroupAd->getPolicySummary();
                    printf(
                        "Ad with ID %d and type '%s' was disapproved with the following policy topic entries:\n",
                        $adGroupAd->getAd()->getId(),
                        $adGroupAd->getAd()->getType()
                    );
                    // Display the policy topic entries related to the ad disapproval.
                    foreach ($policySummary->getPolicyTopicEntries() as $policyTopicEntry) {
                        printf(
                            "  topic id: %s, topic name: '%s', Help Center URL: %s\n",
                            $policyTopicEntry->getPolicyTopicId(),
                            $policyTopicEntry->getPolicyTopicName(),
                            $policyTopicEntry->getPolicyTopicHelpCenterUrl()
                        );
                        // Display the attributes and values that triggered the policy
                        // topic.
                        if ($policyTopicEntry->getPolicyTopicEvidences() === null) {
                            continue;
                        }
                        foreach ($policyTopicEntry->getPolicyTopicEvidences() as $evidence) {
                            printf(
                                "    evidence type: %s\n",
                                $evidence->getPolicyTopicEvidenceType()
                            );
                            $evidenceTextList = $evidence->getEvidenceTextList();
                            if ($evidenceTextList === null) {
                                continue;
                            }
                            for ($i = 0; $i < count($evidenceTextList); $i++) {
                                printf(
                                    "      evidence text[%d]: %s\n",
                                    $i,
                                    $evidenceTextList[$i]
                                );
                            }
                        }
                    }
                }
            }

            $selector->getPaging()->setStartIndex(
                $selector->getPaging()->getStartIndex() + self::PAGE_LIMIT
            );
        } while ($selector->getPaging()->getStartIndex() < $totalNumEntries);
        printf("%d disapproved ads were found.\n", $disapprovedAdsCount);
    }

    public static function main()
    {
        // Generate a refreshable OAuth2 credential for authentication.
        $oAuth2Credential = (new OAuth2TokenBuilder())->fromFile()->build();

        // Construct an API session configured from a properties file and the
        // OAuth2 credentials above.
        $session = (new AdWordsSessionBuilder())->fromFile()->withOAuth2Credential($oAuth2Credential)->build();
        self::runExample(
            new AdWordsServices(),
            $session,
            intval(self::AD_GROUP_ID)
        );
    }
}

GetAllDisapprovedAds::main();

Get all disapproved ads in an ad group using AWQL

<?php
/**
 * Copyright 2017 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

namespace Google\AdsApi\Examples\AdWords\v201809\CampaignManagement;

require __DIR__ . '/../../../../vendor/autoload.php';

use Google\AdsApi\AdWords\AdWordsServices;
use Google\AdsApi\AdWords\AdWordsSession;
use Google\AdsApi\AdWords\AdWordsSessionBuilder;
use Google\AdsApi\AdWords\Query\v201809\ServiceQueryBuilder;
use Google\AdsApi\AdWords\v201809\cm\AdGroupAdService;
use Google\AdsApi\AdWords\v201809\cm\PolicyApprovalStatus;
use Google\AdsApi\Common\OAuth2TokenBuilder;

/**
 * This example gets all disapproved ads in an ad group with AWQL. To get ad
 * groups, run BasicOperation/GetAdGroups.php.
 */
class GetAllDisapprovedAdsWithAwql
{

    const AD_GROUP_ID = 'INSERT_AD_GROUP_ID_HERE';
    const PAGE_LIMIT = 500;

    public static function runExample(
        AdWordsServices $adWordsServices,
        AdWordsSession $session,
        $adGroupId
    ) {
        $adGroupAdService = $adWordsServices->get($session, AdGroupAdService::class);

        // Create an AWQL query.
        $query = (new ServiceQueryBuilder())->select(['Id', 'PolicySummary'])
            ->where('AdGroupId')
            ->equalTo($adGroupId)
            ->where('CombinedApprovalStatus')
            ->equalTo(PolicyApprovalStatus::DISAPPROVED)
            ->orderByAsc('Id')
            ->limit(0, self::PAGE_LIMIT)
            ->build();

        // Create paging controls.
        $disapprovedAdsCount = 0;
        do {
            // Advance the paging offset in subsequent iterations only.
            if (isset($page)) {
                $query->nextPage();
            }

            // Make the query request.
            $page = $adGroupAdService->query(sprintf('%s', $query));

            // Display results from the query.
            if ($page->getEntries() !== null) {
                foreach ($page->getEntries() as $adGroupAd) {
                    $disapprovedAdsCount++;
                    $policySummary = $adGroupAd->getPolicySummary();
                    printf(
                        "Ad with ID %d and type '%s' was disapproved with the following policy topic entries:\n",
                        $adGroupAd->getAd()->getId(),
                        $adGroupAd->getAd()->getType()
                    );
                    // Display the policy topic entries related to the ad disapproval.
                    foreach ($policySummary->getPolicyTopicEntries() as $policyTopicEntry) {
                        printf(
                            "  topic id: %s, topic name: '%s', Help Center URL: %s\n",
                            $policyTopicEntry->getPolicyTopicId(),
                            $policyTopicEntry->getPolicyTopicName(),
                            $policyTopicEntry->getPolicyTopicHelpCenterUrl()
                        );
                        // Display the attributes and values that triggered the policy
                        // topic.
                        if ($policyTopicEntry->getPolicyTopicEvidences() === null) {
                            continue;
                        }
                        foreach ($policyTopicEntry->getPolicyTopicEvidences() as $evidence) {
                            printf(
                                "    evidence type: %s\n",
                                $evidence->getPolicyTopicEvidenceType()
                            );
                            $evidenceTextList = $evidence->getEvidenceTextList();
                            if ($evidenceTextList === null) {
                                continue;
                            }
                            for ($i = 0; $i < count($evidenceTextList); $i++) {
                                printf(
                                    "      evidence text[%d]: %s\n",
                                    $i,
                                    $evidenceTextList[$i]
                                );
                            }
                        }
                    }
                }
            }
        } while ($query->hasNext($page));
        printf("%d disapproved ads were found.\n", $disapprovedAdsCount);
    }

    public static function main()
    {
        // Generate a refreshable OAuth2 credential for authentication.
        $oAuth2Credential = (new OAuth2TokenBuilder())->fromFile()->build();

        // Construct an API session configured from a properties file and the
        // OAuth2 credentials above.
        $session = (new AdWordsSessionBuilder())->fromFile()->withOAuth2Credential($oAuth2Credential)->build();
        self::runExample(
            new AdWordsServices(),
            $session,
            intval(self::AD_GROUP_ID)
        );
    }
}

GetAllDisapprovedAdsWithAwql::main();

Get all campaigns with a specific label

<?php
/**
 * Copyright 2017 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

namespace Google\AdsApi\Examples\AdWords\v201809\CampaignManagement;

require __DIR__ . '/../../../../vendor/autoload.php';

use Google\AdsApi\AdWords\AdWordsServices;
use Google\AdsApi\AdWords\AdWordsSession;
use Google\AdsApi\AdWords\AdWordsSessionBuilder;
use Google\AdsApi\AdWords\v201809\cm\CampaignService;
use Google\AdsApi\AdWords\v201809\cm\OrderBy;
use Google\AdsApi\AdWords\v201809\cm\Paging;
use Google\AdsApi\AdWords\v201809\cm\Predicate;
use Google\AdsApi\AdWords\v201809\cm\PredicateOperator;
use Google\AdsApi\AdWords\v201809\cm\Selector;
use Google\AdsApi\AdWords\v201809\cm\SortOrder;
use Google\AdsApi\Common\OAuth2TokenBuilder;

/**
 * This example gets all campaigns with a specific label. To add a label to
 * campaigns, run AddCampaignLabels.php.
 */
class GetCampaignsByLabel
{

    const LABEL_ID = 'INSERT_LABEL_ID_HERE';
    const PAGE_LIMIT = 500;

    public static function runExample(
        AdWordsServices $adWordsServices,
        AdWordsSession $session,
        $labelId
    ) {
        $campaignService = $adWordsServices->get($session, CampaignService::class);

        // Create a selector to select all campaigns by the specified label.
        $selector = new Selector();
        $selector->setFields(['Id', 'Name', 'Labels']);
        // Labels filtering is performed by ID. You can use CONTAINS_ANY to select
        // campaigns with any of the label IDs, CONTAINS_ALL to select campaigns
        // with all of the label IDs, or CONTAINS_NONE to select campaigns with none
        // of the label IDs.
        $selector->setPredicates(
            [
                new Predicate('Labels', PredicateOperator::CONTAINS_ANY, [$labelId])
            ]
        );
        $selector->setOrdering([new OrderBy('Name', SortOrder::ASCENDING)]);
        $selector->setPaging(new Paging(0, self::PAGE_LIMIT));

        $totalNumEntries = 0;
        do {
            // Retrieve campaigns one page at a time, continuing to request
            // pages until all campaigns have been retrieved.
            $page = $campaignService->get($selector);

            // Print out some information for each campaign.
            if ($page->getEntries() !== null) {
                $totalNumEntries = $page->getTotalNumEntries();
                foreach ($page->getEntries() as $campaign) {
                    printf(
                        "Campaign with name '%s' and ID %d and labels '%s' was found.\n",
                        $campaign->getName(),
                        $campaign->getId(),
                        implode(
                            ', ',
                            array_map(
                                function ($label) {
                                    return sprintf('%d/%s', $label->getId(), $label->getName());
                                },
                                $campaign->getLabels()
                            )
                        )
                    );
                }
            }

            $selector->getPaging()->setStartIndex(
                $selector->getPaging()->getStartIndex() + self::PAGE_LIMIT
            );
        } while ($selector->getPaging()->getStartIndex() < $totalNumEntries);

        printf("Number of results found: %d\n", $totalNumEntries);
    }

    public static function main()
    {
        // Generate a refreshable OAuth2 credential for authentication.
        $oAuth2Credential = (new OAuth2TokenBuilder())->fromFile()->build();

        // Construct an API session configured from a properties file and the
        // OAuth2 credentials above.
        $session = (new AdWordsSessionBuilder())->fromFile()->withOAuth2Credential($oAuth2Credential)->build();
        self::runExample(
            new AdWordsServices(),
            $session,
            intval(self::LABEL_ID)
        );
    }
}

GetCampaignsByLabel::main();

Graduate a trial

<?php
/**
 * Copyright 2017 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

namespace Google\AdsApi\Examples\AdWords\v201809\CampaignManagement;

require __DIR__ . '/../../../../vendor/autoload.php';

use Google\AdsApi\AdWords\AdWordsServices;
use Google\AdsApi\AdWords\AdWordsSession;
use Google\AdsApi\AdWords\AdWordsSessionBuilder;
use Google\AdsApi\AdWords\v201809\cm\Budget;
use Google\AdsApi\AdWords\v201809\cm\BudgetBudgetDeliveryMethod;
use Google\AdsApi\AdWords\v201809\cm\BudgetOperation;
use Google\AdsApi\AdWords\v201809\cm\BudgetService;
use Google\AdsApi\AdWords\v201809\cm\Money;
use Google\AdsApi\AdWords\v201809\cm\Operator;
use Google\AdsApi\AdWords\v201809\cm\Trial;
use Google\AdsApi\AdWords\v201809\cm\TrialOperation;
use Google\AdsApi\AdWords\v201809\cm\TrialService;
use Google\AdsApi\AdWords\v201809\cm\TrialStatus;
use Google\AdsApi\Common\OAuth2TokenBuilder;

/**
 * This example shows how to graduate a trial.
 * See the Campaign Drafts and Experiments guide for more information:
 * https://developers.google.com/adwords/api/docs/guides/campaign-drafts-experiments
 */
class GraduateTrial
{

    const TRIAL_ID = 'INSERT_TRIAL_ID_HERE';

    public static function runExample(
        AdWordsServices $adWordsServices,
        AdWordsSession $session,
        $trialId
    ) {
        $trialService = $adWordsServices->get($session, TrialService::class);
        $budgetService = $adWordsServices->get($session, BudgetService::class);

        // To graduate a trial, you must specify a different budget from the base
        // campaign. The base campaign (in order to have had a trial based on it)
        // must have a non-shared budget, so it cannot be shared with the new
        // independent campaign created by graduation.
        $budget = new Budget();
        $budget->setName('Trial Budget #' . uniqid());
        $money = new Money();
        $money->setMicroAmount(50000000);
        $budget->setAmount($money);
        $budget->setDeliveryMethod(BudgetBudgetDeliveryMethod::STANDARD);

        // Create a budget operation and add it to the operations list.
        $operations = [];
        $operation = new BudgetOperation();
        $operation->setOperand($budget);
        $operation->setOperator(Operator::ADD);
        $operations[] = $operation;

        // Create the budget on the server.
        $budget = $budgetService->mutate($operations)->getValue()[0];

        // Create a trial.
        $trial = new Trial();
        $trial->setId($trialId);
        $trial->setBudgetId($budget->getBudgetId());
        $trial->setStatus(TrialStatus::GRADUATED);

        // Create a trial operation and add it to the operations list.
        $operations = [];
        $operation = new TrialOperation();
        $operation->setOperand($trial);
        $operation->setOperator(Operator::SET);
        $operations[] = $operation;

        // Update the trial on the server.
        $trial = $trialService->mutate($operations)->getValue()[0];

        // Graduation is a synchronous operation, so the campaign is already ready.
        // If you promote instead, make sure to see the polling scheme demonstrated
        // in AddTrial.php to wait for the asynchronous operation to finish.
        printf(
            "Trial with ID %d graduated. Campaign with ID %d was given a new budget"
            . " ID %d and is no longer dependent on this trial.\n",
            $trial->getId(),
            $trial->getTrialCampaignId(),
            $budget->getBudgetId()
        );
    }

    public static function main()
    {
        // Generate a refreshable OAuth2 credential for authentication.
        $oAuth2Credential = (new OAuth2TokenBuilder())->fromFile()->build();

        // Construct an API session configured from a properties file and the
        // OAuth2 credentials above.
        $session = (new AdWordsSessionBuilder())->fromFile()->withOAuth2Credential($oAuth2Credential)->build();
        self::runExample(new AdWordsServices(), $session, intval(self::TRIAL_ID));
    }
}

GraduateTrial::main();

Set ad parameters for a keyword ad group criterion

<?php
/**
 * Copyright 2017 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

namespace Google\AdsApi\Examples\AdWords\v201809\CampaignManagement;

require __DIR__ . '/../../../../vendor/autoload.php';

use Google\AdsApi\AdWords\AdWordsServices;
use Google\AdsApi\AdWords\AdWordsSession;
use Google\AdsApi\AdWords\AdWordsSessionBuilder;
use Google\AdsApi\AdWords\v201809\cm\AdParam;
use Google\AdsApi\AdWords\v201809\cm\AdParamOperation;
use Google\AdsApi\AdWords\v201809\cm\AdParamService;
use Google\AdsApi\AdWords\v201809\cm\Operator;
use Google\AdsApi\Common\OAuth2TokenBuilder;

/**
 * This example sets ad parameters for a keyword. To get keywords, run
 * BasicOperations/GetKeywords.php.
 */
class SetAdParameters
{

    const AD_GROUP_ID = 'INSERT_AD_GROUP_ID_HERE';
    const KEYWORD_ID = 'INSERT_KEYWORD_ID_HERE';

    public static function runExample(
        AdWordsServices $adWordsServices,
        AdWordsSession $session,
        $adGroupId,
        $keywordId
    ) {
        $adParamService = $adWordsServices->get($session, AdParamService::class);

        // Create ad parameters.
        $adParam1 = new AdParam($adGroupId, $keywordId, '100', 1);
        $adParam2 = new AdParam($adGroupId, $keywordId, '$40', 2);

        $adParamOperations = [];

        $adParamOperation1 = new AdParamOperation();
        $adParamOperation1->setOperand($adParam1);
        $adParamOperation1->setOperator(Operator::SET);
        $adParamOperations[] = $adParamOperation1;

        $adParamOperation2 = new AdParamOperation();
        $adParamOperation2->setOperand($adParam2);
        $adParamOperation2->setOperator(Operator::SET);
        $adParamOperations[] = $adParamOperation2;

        // Add ad params on the server.
        $adParams = $adParamService->mutate($adParamOperations);

        // Print out some information about added ad parameters.
        foreach ($adParams as $adParam) {
            printf(
                "Ad parameter with insertion text '%s' and parameter index %d was set.\n",
                $adParam->getInsertionText(),
                $adParam->getParamIndex()
            );
        }
    }

    public static function main()
    {
        // Generate a refreshable OAuth2 credential for authentication.
        $oAuth2Credential = (new OAuth2TokenBuilder())->fromFile()->build();

        // Construct an API session configured from a properties file and the
        // OAuth2 credentials above.
        $session = (new AdWordsSessionBuilder())->fromFile()->withOAuth2Credential($oAuth2Credential)->build();
        self::runExample(
            new AdWordsServices(),
            $session,
            intval(self::AD_GROUP_ID),
            intval(self::KEYWORD_ID)
        );
    }
}

SetAdParameters::main();

Set a bid modifier on a campaign

<?php
/**
 * Copyright 2017 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

namespace Google\AdsApi\Examples\AdWords\v201809\CampaignManagement;

require __DIR__ . '/../../../../vendor/autoload.php';

use Google\AdsApi\AdWords\AdWordsServices;
use Google\AdsApi\AdWords\AdWordsSession;
use Google\AdsApi\AdWords\AdWordsSessionBuilder;
use Google\AdsApi\AdWords\v201809\cm\CampaignCriterion;
use Google\AdsApi\AdWords\v201809\cm\CampaignCriterionOperation;
use Google\AdsApi\AdWords\v201809\cm\CampaignCriterionService;
use Google\AdsApi\AdWords\v201809\cm\Operator;
use Google\AdsApi\AdWords\v201809\cm\Platform;
use Google\AdsApi\Common\OAuth2TokenBuilder;

/**
 * This example sets a bid modifier on a campaign.
 */
class SetBidModifier
{

    const CAMPAIGN_ID = 'INSERT_CAMPAIGN_ID_HERE';
    // Bid modifiers are float number, not percentages, e.g., 1.5 means 50% more
    // bidding.
    const BID_MODIFIER = 'INSERT_BID_MODIFIER_HERE';

    public static function runExample(
        AdWordsServices $adWordsServices,
        AdWordsSession $session,
        $campaignId,
        $bidModifier
    ) {
        $campaignCriterionService = $adWordsServices->get($session, CampaignCriterionService::class);

        // Create a mobile platform. The ID can be found in the documentation.
        // https://developers.google.com/adwords/api/docs/appendix/platforms
        $mobile = new Platform();
        $mobile->setId(30001); // HighEndMobile = 30001

        // Create a criterion with modified bid.
        $criterion = new CampaignCriterion();
        $criterion->setCampaignId($campaignId);
        $criterion->setCriterion($mobile);
        $criterion->setBidModifier($bidModifier);

        // Create a campaign criterion operation and add it to the operations list.
        $operation = new CampaignCriterionOperation();
        $operation->setOperator(Operator::SET);
        $operation->setOperand($criterion);
        $operations = [$operation];

        // Update campaign criteria on the server.
        $results = $campaignCriterionService->mutate($operations);

        // Print out some information about the updated campaign criterion.
        foreach ($results->getValue() as $campaignCriterion) {
            printf(
                "Campaign criterion with campaign ID %d, criterion ID %d, "
                . "and type '%s' was modified with bid %.2f.\n",
                $campaignCriterion->getCampaignId(),
                $campaignCriterion->getCriterion()->getId(),
                $campaignCriterion->getCriterion()->getType(),
                $campaignCriterion->getBidModifier()
            );
        }
    }

    public static function main()
    {
        // Generate a refreshable OAuth2 credential for authentication.
        $oAuth2Credential = (new OAuth2TokenBuilder())->fromFile()->build();

        // Construct an API session configured from a properties file and the
        // OAuth2 credentials above.
        $session = (new AdWordsSessionBuilder())->fromFile()->withOAuth2Credential($oAuth2Credential)->build();
        self::runExample(
            new AdWordsServices(),
            $session,
            intval(self::CAMPAIGN_ID),
            floatval(self::BID_MODIFIER)
        );
    }
}

SetBidModifier::main();

Validate text ad through setValidateOnly header

<?php
/**
 * Copyright 2017 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

namespace Google\AdsApi\Examples\AdWords\v201809\CampaignManagement;

require __DIR__ . '/../../../../vendor/autoload.php';

use Google\AdsApi\AdWords\AdWordsServices;
use Google\AdsApi\AdWords\AdWordsSession;
use Google\AdsApi\AdWords\AdWordsSessionBuilder;
use Google\AdsApi\AdWords\v201809\cm\AdGroupAd;
use Google\AdsApi\AdWords\v201809\cm\AdGroupAdOperation;
use Google\AdsApi\AdWords\v201809\cm\AdGroupAdService;
use Google\AdsApi\AdWords\v201809\cm\ApiException;
use Google\AdsApi\AdWords\v201809\cm\ExpandedTextAd;
use Google\AdsApi\AdWords\v201809\cm\Operator;
use Google\AdsApi\Common\OAuth2TokenBuilder;

/**
 * This example validates a text ad without creating it using the validateOnly
 * mode, which can be useful when checking for policy violations.
 */
class ValidateTextAd
{

    const AD_GROUP_ID = 'INSERT_AD_GROUP_ID_HERE';

    public static function runExample(
        AdWordsServices $adWordsServices,
        AdWordsSession $session,
        $adGroupId
    ) {
        $session->setValidateOnly(true);
        $adGroupAdService = $adWordsServices->get($session, AdGroupAdService::class);

        $operations = [];
        // Create invalid expanded text ad.
        $expandedTextAd = new ExpandedTextAd();
        $expandedTextAd->setHeadlinePart1('Luxury Cruise to Mars !!!');
        $expandedTextAd->setHeadlinePart2('Visit the Red Planet in style.');
        $expandedTextAd->setDescription(
            'Low-gravity fun for all astronauts in orbit.'
        );
        $expandedTextAd->setFinalUrls(['http://www.example.com']);

        // Create ad group ad.
        $adGroupAd = new AdGroupAd();
        $adGroupAd->setAdGroupId($adGroupId);
        $adGroupAd->setAd($expandedTextAd);

        // Create ad group ad operation and add it to the list.
        $operation = new AdGroupAdOperation();
        $operation->setOperand($adGroupAd);
        $operation->setOperator(Operator::ADD);
        $operations[] = $operation;

        try {
            $adGroupAdService->mutate($operations);
            printf("The expanded text ad is valid.\n");
        } catch (ApiException $e) {
            $errors = $e->getErrors();
            if (count($errors) > 0) {
                printf("The expanded text ad is invalid for the following reasons:\n");
                foreach ($errors as $error) {
                    printf(
                        "  %s @ %s\n",
                        $error->getErrorString(),
                        $error->getFieldPath()
                    );
                }
            }
        }
    }

    public static function main()
    {
        // Generate a refreshable OAuth2 credential for authentication.
        $oAuth2Credential = (new OAuth2TokenBuilder())->fromFile()->build();

        // Construct an API session configured from a properties file and the
        // OAuth2 credentials above.
        $session = (new AdWordsSessionBuilder())->fromFile()->withOAuth2Credential($oAuth2Credential)->build();
        self::runExample(
            new AdWordsServices(),
            $session,
            intval(self::AD_GROUP_ID)
        );
    }
}

ValidateTextAd::main();

Feedback geben zu...