Export (0) Print
Expand All

Product Ads in PHP

The following example shows how to add a product extension and associate it with a campaign, add product criterion to an ad group, get and update the criterion, and add promotional text to product ads.

This example has been developed and run within the environment described in Getting Started Using PHP with Bing Ads Services.

To download the PHP classes included in the sample, see PHP Production Classes for Bing Ads API.

System_CLiX_note Note

This example uses the UserName and Password elements for authentication. For Managing User Authentication with OAuth, replace the UserName and Password elements with the AuthenticationToken, which is your OAuth access token.

<?php

// This example is intended to be run from a Windows Command prompt.
// You must pass the URL of the Campaign Management WSDL.

// Usage:
//
// php.exe ProductAds wsdl"

// This program requires the following PHP extensions:
//    php_soap.dll
//    php_openssl.dll


// Disable WSDL caching.

ini_set("soap.wsdl_cache_enabled", "0");
ini_set("soap.wsdl_cache_ttl", "0");

// API credentials.

$username = "<usernamegoeshere>";
$password = "<passwordgoeshere>";
$token = "<devtokengoeshere>";

// Advertiser's account ID and customer ID.

$accountId = <accountidgoeshere>;
$customerId = <customeridgoeshere>;

// The ID of the campaign and ad group to add the product criterions to.

$campaignId = '<campaignidgoeshere>';
$adGroupId = '<adgroupidgoeshere>';

// Campaign Management WSDL passed as argument

$wsdl = $argv[1];

$productAdIds = null;
$criterionIds = null;
$criterions = null;


try
{
    $proxy = new ClientProxy($username, $password, $token, $accountId, $customerId, $wsdl);

    // Create the product extension and associate it with a campaign.

    $adExtensionIds = AddProductExtensions($accountId, $proxy);
    AssociateExtensionsWithCampaign($accountId, $campaignId, $adExtensionIds[0], $proxy);

    // Create a product criterion for the ad group.

    $criterionIds = AddProductCriterions($accountId, $adGroupId, $proxy);
    $criterions = GetCriterionsByIds($accountId, $criterionIds, $proxy);
    PrintAdGroupCriterions($criterionIds, $criterions);

    // Provide the promotional text that gets added to product ads.

    $productAdIds = AddPromotionalText($adGroupId, $proxy);

    // Update the product criterion.

    $criterions = GetCriterionsByAdGroup($accountId, $adGroupId, $proxy);
    UpdateProductCriterion($accountId, $criterions, $proxy);
    $criterions = GetCriterionsByAdGroup($accountId, $adGroupId, $proxy);
    PrintAdGroupCriterions($criterionIds, $criterions);
}
catch (SoapFault $e)
{
    print $e->getMessage()."\n\n";
}
catch (Exception $e)
{
    if ($e->getPrevious())
    {
        ; // Ignore fault exceptions that we already caught.
    }
    else
    {
        print $e->getCode()." ".$e->getMessage()."\n\n";
        print $e->getTraceAsString()."\n\n";
    }
}

// Adds a product ad extension to the account's ad extension library.
// The extension is used to associate a campaign with the customer's
// Bing Merchant Center (BMC) store.

function AddProductExtensions($accountId, $proxy)
{
    $request = new AddAdExtensionsRequest();
    $response = null; // AddAdExtensionsResponse
    $ids = null;

    // Set the request information.

    $request->AccountId = $accountId;
    $request->AdExtensions = array();

    // Specify the extensions.

    $extension = new ProductAdExtension();
    $extension->Name = 'Basketball Shoes';
    $extension->StoreId = <storeidgoeshere>; // Customer's BMC store ID
    $extension->StoreName = null; // Read-only, must be null

    // Optional filter that identifies the products in the store
    // to advertise. The product is selected if it meets the conditions
    // in collection 1 OR the conditions in collection 2, and so on.
    // If null (no conditions are specified), Bing
    // can create product ads for all products in the store.
    // If the product criterion specifies a filter, the product
    // must also meet the conditions of the criterion filter.

    $extension->ProductSelection = array();

    // Specify the first collection of product conditions.

    $collection = new ProductConditionCollection();

    $collection->Conditions = array();

    $condition = new ProductCondition();
    $condition->Operand = 'ProductType';
    $condition->Attribute = 'Apparel > Shoes > Basketball > Mens';
    $collection->Conditions[] = $condition;

    $condition = new ProductCondition();
    $condition->Operand = 'Brand';
    $condition->Attribute = 'Speedy Speedsters';
    $collection->Conditions[] = $condition;

    $extension->ProductSelection[] = $collection;
    
    // Specify the second collection of product conditions.

    $collection = new ProductConditionCollection();

    $collection->Conditions = array();

    $condition = new ProductCondition();
    $condition->Operand = 'ProductType';
    $condition->Attribute = 'Apparel > Shoes > Basketball > Boys';
    $collection->Conditions[] = $condition;

    $condition = new ProductCondition();
    $condition->Operand = 'Brand';
    $condition->Attribute = 'Speedy Speedsters';
    $collection->Conditions[] = $condition;

    $extension->ProductSelection[] = $collection;

    // Encode the product extension and add it to the list.

    $encodedExtension = new SoapVar($extension, SOAP_ENC_OBJECT, 'ProductAdExtension', $proxy->GetNamespace());
    $request->AdExtensions[] = $encodedExtension;

    try
    {
        $response = $proxy->GetService()->AddAdExtensions($request);

        foreach ($response->AdExtensionIdentities->AdExtensionIdentity as $entity)
        {
            $ids[] = $entity->Id;
        }
    }
    catch (SoapFault $e)
    {
        // Log this fault.

        print "AddAdExtensions failed with the following faults:\n";

        if (isset($e->detail->AdApiFaultDetail))
        {
            print "AdApiFaultDetail exception encountered\n";
            print "Tracking ID: ".$e->detail->AdApiFaultDetail->TrackingId ."\n";

            // Process any system errors.

            $errors = is_array($e->detail->AdApiFaultDetail->Errors->AdApiError)
                    ? $e->detail->AdApiFaultDetail->Errors->AdApiError
                    : array('AdApiError' => $e->detail->AdApiFaultDetail->Errors->AdApiError);

            foreach ($errors as $error)
            {
                if (105 == $error->Code) //  InvalidCredentials
                {
                    print "The specified credentials are not valid or the account is inactive.\n";
                }
                else
                {
                    printf("Error code: %s (%d)\nMessage: %s\nDetail: %s\n\n",
                        $error->ErrorCode, $error->Code, $error->Message, $error->Detail);
                }
            }
        }
        elseif (isset($e->detail->ApiFaultDetail))
        {
            print "ApiFaultDetail exception encountered\n";
            print "Tracking ID: ".$e->detail->ApiFaultDetail->TrackingId."\n";

            // Process any operation errors.

            if (!empty($e->detail->ApiFaultDetail->OperationErrors))
            {
                $errors = is_array($e->detail->ApiFaultDetail->OperationErrors->OperationError)
                        ? $e->detail->ApiFaultDetail->OperationErrors->OperationError
                        : array('OperationError' => $e->detail->ApiFaultDetail->OperationErrors->OperationError);

                foreach ($errors as $error)
                {
                    switch ($error->Code)
                    {
                        case 106: //  UserIsNotAuthorized
                            print("The user is not authorized to call this operation.\n");
                            break;

                        case 1030: //  CampaignServiceAccountIdHasToBeSpecified
                            print("The CustomerAccountId header element " .
                                "cannot be null or empty.\n");
                            break;

                        case 3862: // CampaignServiceLocationAdExtensionsEntityLimitExceeded
                            print("The number of location ad extensions in the " .
                                "ad extensions list exceeds the maximum allowed.\n");
                            break;

                        default:
                            printf("Error code: %s (%d)\nMessage: %s\nDetail: %s\n\n",
                                $error->ErrorCode, $error->Code, $error->Message, $error->Details);
                            break;
                    }
                }
            }

            // Process any batch errors.

            // This list of errors codes is just a sampling of the possible errors that
            // AddAdExtensions can throw.

            // Note that the Details element of BatchErrors contains the zero-based
            // index of the product collection that caused the error.

            if (!empty($e->detail->ApiFaultDetail->BatchErrors))
            {
                $errors = is_array($e->detail->ApiFaultDetail->BatchErrors->BatchError)
                        ? $e->detail->ApiFaultDetail->BatchErrors->BatchError
                        : array('BatchError' => $e->detail->ApiFaultDetail->BatchErrors->BatchError);

                foreach ($errors as $error)
                {
                    switch ($error->Code)
                    {
                        case 3863: // CampaignServiceProductAdExtensionPilotNotEnabledForCustomer
                            printf("To add product extensions, the customer " .
                                "must be a member of the Product Ads pilot program.\n\n");
                            break;

                        case 3864: // CampaignServiceProductAdExtensionTooManyProductConditionCollections
                            printf("Failed to add product extension #%d. The " .
                                "list of product condition collections is too long.\n\n",
                                $error->Index);
                            break;

                        case 3865: // CampaignServiceProductAdExtensionTooManyConditions
                            printf("Failed to add product extension #%d. Product " .
                                "condition collection #%s contains too many conditions.\n\n",
                                $error->Index,
                                $error->Details);
                            break;

                        case 3866: // CampaignServiceProductAdExtensionInvalidStoreId
                            printf("Failed to add product extension #%d. The store " .
                                "ID is not valid.\n\n",
                                $error->Index);
                            break;

                        case 3867: // CampaignServiceProductAdExtensionProductConditionsArrayIsNullOrEmpty
                            printf("Failed to add product extension #%d. Product " .
                                "condition collection #%s cannot be null or empty.\n\n",
                                $error->Index,
                                $error->Details);
                            break;

                        case 3869: // CampaignServiceProductAdExtensionOperandIsInvalid
                            printf("Failed to add product extension #%d. One of the " .
                                "operands in product condition collection #%s is not valid.\n\n",
                                $error->Index,
                                $error->Details);
                            break;

                        case 3870: // CampaignServiceProductAdExtensionAttributeIsInvalid
                            printf("Failed to add product extension #%d. One of the " .
                                "attributes in product condition collection #%s is not valid.\n\n",
                                $error->Index,
                                $error->Details);
                            break;

                        case 4116: // CampaignServiceProductConditionAttributeNullOrEmpty
                            printf("Failed to add product extension #%d. The attributes " .
                                "in product condition collection #%s cannot be null or empty.\n\n",
                                $error->Index,
                                $error->Details);
                            break;

                        default:
                            printf("Error code: %s (%d)\nIndex: %d\nMessage: %s\nDetail: %s\n\n",
                                $error->ErrorCode, $error->Code, $error->Index, $error->Message, $error->Details);
                            break;
                    }
                }
            }
        }
        else
        {
            print $e->getCode()." ".$e->getMessage()."\n\n";

            // Output the last request/response.

            print "\nLast SOAP request/response:\n";
            print $proxy->GetWsdl()."\n";
            print $proxy->GetService()->__getLastRequest()."\n";
            print $proxy->GetService()->__getLastResponse()."\n";
        }

        throw new Exception("", 0, $e);
    }

    return $ids;
}

// Associates the product extension with a campaign. A campaign can be associated
// with only one product extension.

function AssociateExtensionsWithCampaign($accountId, $campaignId, $extensionId, $proxy)
{
    $request = new SetAdExtensionsToCampaignsRequest();
    $response = null; // SetAdExtensionsToCampaignsResponse

    $associations = array();

    $association = new AdExtensionIdToCampaignIdAssociation();
    $association->AdExtensionId = $extensionId;
    $association->CampaignId = $campaignId;

    $associations[] = $association;

    // Set the request information.

    $request->AccountId = $accountId;
    $request->AdExtensionIdToCampaignIdAssociations = $associations;

    try
    {
        $response = $proxy->GetService()->SetAdExtensionsToCampaigns($request);
    }
    catch (SoapFault $e)
    {
        // Log this fault.

        print("SetAdExtensionsToCampaigns failed with the following faults:\n");

        if (isset($e->detail->AdApiFaultDetail))
        {
            print "AdApiFaultDetail exception encountered\n";
            print "Tracking ID: ".$e->detail->AdApiFaultDetail->TrackingId ."\n";

            // Process any system errors.

            $errors = is_array($e->detail->AdApiFaultDetail->Errors->AdApiError)
                    ? $e->detail->AdApiFaultDetail->Errors->AdApiError
                    : array('AdApiError' => $e->detail->AdApiFaultDetail->Errors->AdApiError);

            foreach ($errors as $error)
            {
                if (105 == $error->Code) //  InvalidCredentials
                {
                    print "The specified credentials are not valid or the account is inactive.\n";
                }
                else
                {
                    printf("Error code: %s (%d)\nMessage: %s\nDetail: %s\n\n",
                        $error->ErrorCode, $error->Code, $error->Message, $error->Detail);
                }
            }
        }
        elseif (isset($e->detail->ApiFaultDetail))
        {
            print "ApiFaultDetail exception encountered\n";
            print "Tracking ID: ".$e->detail->ApiFaultDetail->TrackingId."\n";

            // Process any operation errors.

            if (!empty($e->detail->ApiFaultDetail->OperationErrors))
            {
                $errors = is_array($e->detail->ApiFaultDetail->OperationErrors->OperationError)
                        ? $e->detail->ApiFaultDetail->OperationErrors->OperationError
                        : array('OperationError' => $e->detail->ApiFaultDetail->OperationErrors->OperationError);

                foreach ($errors as $error)
                {
                    switch ($error->Code)
                    {
                        case 106: //  UserIsNotAuthorized
                            print("The user is not authorized to call this operation.\n");
                            break;

                        case 1030: //  CampaignServiceAccountIdHasToBeSpecified
                            print("The CustomerAccountId header element " .
                                "cannot be null or empty.\n");
                            break;

                        case 1102: //  CampaignServiceInvalidAccountId
                            print("The account ID is not valid.\n");
                            break;

                        case 3810: //  CampaignServiceAdExtensionIdToCampaignIdAssociationArrayShouldNotBeN
                            print("The list of ad extension to campaign " .
                                "associations cannot be null or empty.\n");
                            break;

                        default:
                            printf("Error code: %s (%d)\nMessage: %s\nDetail: %s\n\n",
                                $error->ErrorCode, $error->Code, $error->Message, $error->Details);
                            break;
                    }
                }
            }

            // Process any batch errors.

            if (!empty($e->detail->ApiFaultDetail->BatchErrors))
            {
                $errors = is_array($e->detail->ApiFaultDetail->BatchErrors->BatchError)
                        ? $e->detail->ApiFaultDetail->BatchErrors->BatchError
                        : array('BatchError' => $e->detail->ApiFaultDetail->BatchErrors->BatchError);

                foreach ($errors as $error)
                {
                    switch ($error->Code)
                    {
                        case 1100: //  CampaignServiceInvalidCampaignId
                            printf("The campaign ID specified in ad extension " .
                                "to campaign association #%d is not valid.\n\n",
                                $error->Index);
                            break;

                        case 1397: //  CampaignServiceEditorialGenericError
                            printf("The ad extension specified in ad extension " .
                                "to campaign association #%d failed editorial review. " .
                                "The term that failed review is \"%s\".\n\n",
                                $error->Index,
                                $error->Details);
                            break;

                        case 3812: //  CampaignServiceInvalidAdExtensionId
                            printf("The ad extension ID specified in ad " .
                                "extension to campaign association #%d is not valid.\n\n",
                                $error->Index);
                            break;

                        case 3818: //  CampaignServiceCannotAssignMoreThanOneAdExtensionTypeToAnEntity
                            printf("The campaign specified in ad extension to " .
                                "campaign association #%d can contain only one extension of " .
                                "the specified type.\n\n",
                                $error->Index);
                            break;

                        case 3825: //  CampaignServiceDuplicateInAdExtensionIdToCampaignIdAssociations
                            printf("The list of ad extension to campaign " .
                                "associations contains a duplicate ad extension ID " .
                                "for the same campaign. Association #%d contains the duplicate.\n\n",
                                $error->Index);
                            break;

                        case 3856: //  CampaignServiceLocationAdExtensionPilotNotEnabledForCustomer
                            print("To call this operation, the customer must be a " .
                                "member of the location ad extensions pilot program.\n\n");
                            break;

                        case 3857: //  CampaignServiceCallAdExtensionPilotNotEnabledForCustomer
                            print("To call this operation, the customer must be a " .
                                "member of the call ad extensions pilot program.\n\n");
                            break;

                        default:
                            printf("Error code: %s (%d)\nIndex: %d\nMessage: %s\nDetail: %s\n\n",
                                $error->ErrorCode, $error->Code, $error->Index, $error->Message, $error->Details);
                            break;
                    }
                }
            }
        }
        else
        {
            print $e->getCode()." ".$e->getMessage()."\n\n";

            // Output the last request/response.

            print "\nLast SOAP request/response:\n";
            print $proxy->GetWsdl()."\n";
            print $proxy->GetService()->__getLastRequest()."\n";
            print $proxy->GetService()->__getLastResponse()."\n";
        }

        throw new Exception("", 0, $e);
    }
}

// Adds a ProductAd to the specified ad group. Do not confuse a ProductAd object with
// a product ad that the delivery engine generates. A ProductAd is optional.
// Its purpose is to provide promotional text that the delivery engine adds to
// the product ads that it generates and to provide a way to get performance-based
// reporting (clicks and impressions) for the product ads.

function AddPromotionalText($adGroupId, $proxy)
{
    $request = new AddAdsRequest();
    $response = null; // AddAdsResponse

    // Specify the promotional text to add to the ad group. If your only
    // purpose for adding ProductAd objects is to get reporting, set 
    // PromotionalText to null or an empty string.

    $ads = array();
    $ad = new ProductAd();
    $ad->PromotionalText = 'Free shipping on $99 purchases.';
    $encodedAd = new SoapVar($ad, SOAP_ENC_OBJECT, 'ProductAd', $proxy->GetNamespace());
    $ads[] = $encodedAd;

    // Set the request information.

    $request->AdGroupId = $adGroupId;
    $request->Ads = $ads;

    try
    {
        $response = $proxy->GetService()->AddAds($request);

        print("Added product ads with the following IDs.\n");

        foreach ($response->AdIds->long as $id)
        {
            print($id."\n");
        }

        print("\n");
    }
    catch (SoapFault $e)
    {
        print "AddAds failed.\n";

        if (isset($e->detail->EditorialApiFaultDetail))
        {
            print "EditorialApiFaultDetail exception encountered\n";
            print "Tracking ID: ".$e->detail->EditorialApiFaultDetail->TrackingId."\n";

            // Process any operation errors.

            if (!empty($e->detail->EditorialApiFaultDetail->OperationErrors))
            {
                $errors = is_array($e->detail->EditorialApiFaultDetail->OperationErrors->OperationError)
                        ? $e->detail->EditorialApiFaultDetail->OperationErrors->OperationError
                        : array('OperationError' => $e->detail->EditorialApiFaultDetail->OperationErrors->OperationError);

                foreach ($errors as $error)
                {
                    switch ($error->Code)
                    {
                        case 106: //  UserIsNotAuthorized
                            print("The user is not authorized to call this operation.\n\n");
                            break;

                        case 1030: //  CampaignServiceAccountIdHasToBeSpecified
                            print("The CustomerAccountId header element cannot be null or empty.\n\n");
                            break;

                        default:
                            printf("Error code: %s (%d)\nMessage: %s\nDetail: %s\n\n",
                                $error->ErrorCode, $error->Code, $error->Message, $error->Details);
                            break;
                    }
                }
            }

            // Process any batch errors.

            if (!empty($e->detail->EditorialApiFaultDetail->BatchErrors))
            {
                $errors = is_array($e->detail->EditorialApiFaultDetail->BatchErrors->BatchError)
                        ? $e->detail->EditorialApiFaultDetail->BatchErrors->BatchError
                        : array('BatchError' => $e->detail->EditorialApiFaultDetail->BatchErrors->BatchError);

                foreach ($errors as $error)
                {
                    switch ($error->Code)
                    {
                        case 1313: // CampaignServiceDuplicateAd
                            printf("Product ad #%d is a duplicate of another product ad in the list.\n\n",
                                $error->Index);
                            break;

                        case 1366: // CampaignServiceAdTypeInvalidForCustomer
                            print("To add product ads, the customer " .
                                "must be a member of the Product Ads pilot program.\n\n");
                            break;

                        case 1398: // CampaignServiceProductAdPromotionalTextTooLong
                            printf("The promotional text of ad #%d is too long.\n\n",
                                $error->Index);
                            break;

                        default:
                            print "Batch error encountered for array index ".$error->Index.".\n";
                            printf("Error code: %s (%d)\nMessage: %s\nDetail: %s\n\n",
                                $error->ErrorCode, $error->Code, $error->Message, $error->Details);
                            break;
                    }
                }
            }

            // Process any editorial errors.

            if (!empty($e->detail->EditorialApiFaultDetail->EditorialErrors))
            {
                $errors = is_array($e->detail->EditorialApiFaultDetail->EditorialErrors->EditorialError)
                        ? $e->detail->EditorialApiFaultDetail->EditorialErrors->EditorialError
                        : array('EditorialError' => $e->detail->EditorialApiFaultDetail->EditorialErrors->EditorialError);

                foreach ($errors as $error)
                {
                    switch ($error->Code)
                    {
                        default:
                            print "Editorial error encountered for array index ".$error->Index.".\n";
                            printf("Error code: %s (%d)\nMessage: %s\n",
                                $error->ErrorCode, $error->Code, $error->Message);
                            printf("Appealable: %s\nDisapproved text: %s\nCountry: %s\n\n",
                                $error->Appealable, $error->DisapprovedText, $error->PublisherCountry);
                            break;
                    }
                }
            }
        }
        elseif (isset($e->detail->AdApiFaultDetail))
        {
            print "AdApiFaultDetail exception encountered\n";
            print "Tracking ID: ".$e->detail->AdApiFaultDetail->TrackingId ."\n";

            // Process any system errors.

            $errors = is_array($e->detail->AdApiFaultDetail->Errors->AdApiError)
                    ? $e->detail->AdApiFaultDetail->Errors->AdApiError
                    : array('AdApiError' => $e->detail->AdApiFaultDetail->Errors->AdApiError);

            foreach ($errors as $error)
            {
                if (105 == $error->Code) //  InvalidCredentials
                {
                    print "The specified credentials are not valid or the account is inactive.\n\n";
                }
                else
                {
                    printf("Error code: %s (%d)\nMessage: %s\nDetail: %s\n\n",
                        $error->ErrorCode, $error->Code, $error->Message, $error->Detail);
                }
            }
        }
        else
        {
            print $e->getCode()." ".$e->getMessage()."\n\n";

            // Output the last request/response.

            print "\nLast SOAP request/response:\n";
            print $proxy->GetWsdl()."\n";
            print $proxy->GetService()->__getLastRequest()."\n";
            print $proxy->GetService()->__getLastResponse()."\n";
        }

        throw new Exception("", 0, $e);
    }

    return $response->AdIds->long;
}

// Add the product criterions to the ad group. A criterion specifies a
// bid value and optional product condition filter.

function AddProductCriterions($accountId, $adGroupId, $proxy)
{
    $request = new AddAdGroupCriterionsRequest();
    $response = null;  // AddAdGroupCriterionsResponse

    // Specify the product criterions. The product ad gets served if the product
    // matches the criterion's filter AND the product ad extension filter.

    $criterions = array();

    // Specify biddable criterion #1.

    $biddableCriterion = new BiddableAdGroupCriterion();

    $biddableCriterion->AdGroupId = $adGroupId;
    $biddableCriterion->DestinationUrl = null;  // Overrides the product store's destination URL
    $biddableCriterion->Param1 = null;          // Substitution strings for DestinationUrl
    $biddableCriterion->Param2 = null;
    $biddableCriterion->Param3 = null;

    $fixedBid = new FixedBid();
    $fixedBid->Bid = new Bid();
    $fixedBid->Bid->Amount = 1.05;
    $encodedBid = new SoapVar($fixedBid, SOAP_ENC_OBJECT, 'FixedBid', $proxy->GetNamespace());
    $biddableCriterion->CriterionBid = $encodedBid;

    $product = new Product();
    $product->Conditions = array();
    $condition = new ProductCondition();
    $condition->Operand = 'SKU';
    $condition->Attribute = '11EEE';
    $product->Conditions[] = $condition;

    $encodedProduct = new SoapVar($product, SOAP_ENC_OBJECT, 'Product', $proxy->GetNamespace());
    $biddableCriterion->Criterion = $encodedProduct;

    $encodedbiddableCriterion = new SoapVar($biddableCriterion, SOAP_ENC_OBJECT, 'BiddableAdGroupCriterion', $proxy->GetNamespace());
    $criterions[] = $encodedbiddableCriterion;

    // Specify biddable criterion #2.

    $biddableCriterion = new BiddableAdGroupCriterion();

    $biddableCriterion->AdGroupId = $adGroupId;

    $bid = new Bid();
    $bid->Amount = null; // Default to the ad group's exact-match bid value
    $fixedBid = new FixedBid();
    $fixedBid->Bid = $bid;
    $encodedBid = new SoapVar($fixedBid, SOAP_ENC_OBJECT, 'FixedBid', $proxy->GetNamespace());
    $biddableCriterion->CriterionBid = $encodedBid;

    $product = new Product();
    $product->Conditions = array();
    $condition = new ProductCondition();
    $condition->Operand = 'SKU';
    $condition->Attribute = '12EEE';
    $product->Conditions[] = $condition;

    $encodedProduct = new SoapVar($product, SOAP_ENC_OBJECT, 'Product', $proxy->GetNamespace());
    $biddableCriterion->Criterion = $encodedProduct;

    $encodedbiddableCriterion = new SoapVar($biddableCriterion, SOAP_ENC_OBJECT, 'BiddableAdGroupCriterion', $proxy->GetNamespace());
    $criterions[] = $encodedbiddableCriterion;

    // Set the request information.

    $request->AccountId = $accountId;
    $request->AdGroupCriterions = $criterions;

    try
    {
        $response = $proxy->GetService()->AddAdGroupCriterions($request);
    }
    catch (SoapFault $e)
    {
        print "AddAdGroupCriterions failed.\n";

        if (isset($e->detail->ApiFaultDetail))
        {
            print "ApiFaultDetail exception encountered\n";
            print "Tracking ID: ".$e->detail->ApiFaultDetail->TrackingId."\n";

            // Process any operation errors.

            if (!empty($e->detail->ApiFaultDetail->OperationErrors))
            {
                $errors = is_array($e->detail->ApiFaultDetail->OperationErrors->OperationError)
                        ? $e->detail->ApiFaultDetail->OperationErrors->OperationError
                        : array('OperationError' => $e->detail->ApiFaultDetail->OperationErrors->OperationError);

                foreach ($errors as $error)
                {
                    switch ($error->Code)
                    {
                        case 1030: //  CampaignServiceAccountIdHasToBeSpecified
                            print("You must specify the account ID in the CustomerAccountId header element.\n");
                            break;

                        case 3863: // CampaignServiceProductAdExtensionPilotNotEnabledForCustomer
                            print("To add ad group criterions, the customer " .
                                "must be a member of the Product Ads pilot program.\n");
                            break;

                        case 4104: // CampaignServiceAdGroupCriterionsNullOrEmpty
                            print("To list of ad group criterions cannot be null or empty.\n");
                            break;

                        default:
                            printf("Error code: %s (%d)\nMessage: %s\nDetail: %s\n",
                                $error->ErrorCode, $error->Code, $error->Message, $error->Details);
                            break;
                    }
                }
            }

            // Process any batch errors.

            if (!empty($e->detail->ApiFaultDetail->BatchErrors))
            {
                $errors = is_array($e->detail->ApiFaultDetail->BatchErrors->BatchError)
                        ? $e->detail->ApiFaultDetail->BatchErrors->BatchError
                        : array('BatchError' => $e->detail->ApiFaultDetail->BatchErrors->BatchError);

                foreach ($errors as $error)
                {
                    switch ($error->Code)
                    {
                        case 1515: // CampaignServiceBidAmountsLessThanFloorPrice
                            printf("The bid value of ad group criterion #%d is " .
                                "less than the minimum allowed bid value.\n\n",
                                $error->Index);
                            break;

                        case 1516: // CampaignServiceBidAmountsGreaterThanCeilingPrice
                            printf("The bid value of ad group criterion #%d exceeds " .
                                "the maximum allowed bid value.\n\n",
                                $error->Index);
                            break;

                        case 3869: // CampaignServiceProductAdExtensionOperandIsInvalid
                            printf("Product operand #%s of ad group criterion #%d " .
                                "is not valid.\n\n",
                                $error->Details,
                                $error->Index);
                            break;

                        case 3870: // CampaignServiceProductAdExtensionAttributeIsInvalid
                            printf("Product attribute #%s of ad group criterion #%d " .
                                "is not valid.\n\n",
                                $error->Details,
                                $error->Index);
                            break;

                        case 3872: // CampaignServiceProductConditionDuplicateOperand
                            printf("Ad group criterion #%s contains duplicate product operands. " .
                                "Product operand #%d is a duplicate.\n\n",
                                $error->Details,
                                $error->Index);
                            break;

                        case 4108: // CampaignServiceAdGroupCriterionInvalidBidType
                            printf("The bid of ad group criterion #%d is null or " .
                                "is of the wrong type.\n\n",
                                $error->Index);
                            break;

                        case 4109: // CampaignServiceAdGroupCriterionInvalidBidValue
                            printf("The bid value of ad group criterion #%d is not valid.\n\n",
                                $error->Index);
                            break;

                        case 4113: // CampaignServiceProductAdGroupCriterionTooManyConditions
                            printf("The list of product conditions of ad group " .
                                "criterion #%d is too long.\n\n",
                                $error->Index);
                            break;

                        default:
                            print "Batch error encountered for array index ".$error->Index.".\n";
                            printf("Error code: %s (%d)\nMessage: %s\nDetail: %s\n\n",
                                $error->ErrorCode, $error->Code, $error->Message, $error->Details);
                            break;
                    }
                }
            }
        }
        elseif (isset($e->detail->AdApiFaultDetail))
        {
            print "AdApiFaultDetail exception encountered\n";
            print "Tracking ID: ".$e->detail->AdApiFaultDetail->TrackingId ."\n";

            // Process any system errors.

            $errors = is_array($e->detail->AdApiFaultDetail->Errors->AdApiError)
                    ? $e->detail->AdApiFaultDetail->Errors->AdApiError
                    : array('AdApiError' => $e->detail->AdApiFaultDetail->Errors->AdApiError);

            foreach ($errors as $error)
            {
                if (105 == $error->Code) //  InvalidCredentials
                {
                    print "The specified credentials are not valid or the account is inactive.\n";
                }
                else
                {
                    printf("Error code: %s (%d)\nMessage: %s\nDetail: %s\n",
                        $error->ErrorCode, $error->Code, $error->Message, $error->Detail);
                }
            }
        }
        else
        {
            print $e->getCode()." ".$e->getMessage()."\n\n";

            // Output the last request/response.

            print "\nLast SOAP request/response:\n";
            print $proxy->GetWsdl()."\n";
            print $proxy->GetService()->__getLastRequest()."\n";
            print $proxy->GetService()->__getLastResponse()."\n";
        }

        throw new Exception("", 0, $e);
    }

    return $response->AdGroupCriterionIds->long;
}

// Gets the specified list of ad group criterions.

function GetCriterionsByIds($accountId, $adGroupCriterionIds, $proxy)
{
    $request = new GetAdGroupCriterionsByIdsRequest();
    $response = null; // GetAdGroupCriterionsByIdsResponse

    // Set the request information.

    $request->AccountId = $accountId;
    $request->AdGroupCriterionIds = $adGroupCriterionIds;

    try
    {
        $response = $proxy->GetService()->GetAdGroupCriterionsByIds($request);
    }
    catch (SoapFault $e)
    {
        print "GetAdGroupCriterionsByIds failed.\n";

        if (isset($e->detail->ApiFaultDetail))
        {
            print "ApiFaultDetail exception encountered\n";
            print "Tracking ID: ".$e->detail->ApiFaultDetail->TrackingId."\n";

            // Process any operation errors.

            if (!empty($e->detail->ApiFaultDetail->OperationErrors))
            {
                $errors = is_array($e->detail->ApiFaultDetail->OperationErrors->OperationError)
                        ? $e->detail->ApiFaultDetail->OperationErrors->OperationError
                        : array('OperationError' => $e->detail->ApiFaultDetail->OperationErrors->OperationError);

                foreach ($errors as $error)
                {
                    switch ($error->Code)
                    {
                        case 1030: //  CampaignServiceAccountIdHasToBeSpecified
                            print("You must specify the account ID in the CustomerAccountId header element.\n");
                            break;

                        case 4101: //  CampaignServiceAdGroupCriterionIdArrayNullOrEmpty
                            print("The list of ad group criterion IDs cannot be null or empty.\n");
                            break;

                        default:
                            printf("Error code: %s (%d)\nMessage: %s\nDetail: %s\n",
                                $error->ErrorCode, $error->Code, $error->Message, $error->Details);
                            break;
                    }
                }
            }

            // Process any batch errors.

            if (!empty($e->detail->ApiFaultDetail->BatchErrors))
            {
                $errors = is_array($e->detail->ApiFaultDetail->BatchErrors->BatchError)
                        ? $e->detail->ApiFaultDetail->BatchErrors->BatchError
                        : array('BatchError' => $e->detail->ApiFaultDetail->BatchErrors->BatchError);

                foreach ($errors as $error)
                {
                    switch ($error->Code)
                    {
                        default:
                            print "Batch error encountered for array index ".$error->Index.".\n";
                            printf("Error code: %s (%d)\nMessage: %s\nDetail: %s\n\n",
                                $error->ErrorCode, $error->Code, $error->Message, $error->Details);
                            break;
                    }
                }
            }
        }
        elseif (isset($e->detail->AdApiFaultDetail))
        {
            print "AdApiFaultDetail exception encountered\n";
            print "Tracking ID: ".$e->detail->AdApiFaultDetail->TrackingId ."\n";

            // Process any system errors.

            $errors = is_array($e->detail->AdApiFaultDetail->Errors->AdApiError)
                    ? $e->detail->AdApiFaultDetail->Errors->AdApiError
                    : array('AdApiError' => $e->detail->AdApiFaultDetail->Errors->AdApiError);

            foreach ($errors as $error)
            {
                if (105 == $error->Code) //  InvalidCredentials
                {
                    print "The specified credentials are not valid or the account is inactive.\n";
                }
                else
                {
                    printf("Error code: %s (%d)\nMessage: %s\nDetail: %s\n",
                        $error->ErrorCode, $error->Code, $error->Message, $error->Detail);
                }
            }
        }
        else
        {
            print $e->getCode()." ".$e->getMessage()."\n\n";

            // Output the last request/response.

            print "\nLast SOAP request/response:\n";
            print $proxy->GetWsdl()."\n";
            print $proxy->GetService()->__getLastRequest()."\n";
            print $proxy->GetService()->__getLastResponse()."\n";
        }

        throw new Exception("", 0, $e);
    }

    return $response->AdGroupCriterions;
}

// Gets all criterion of the specified type from the ad group.

function GetCriterionsByAdGroup($accountId, $adGroupId, $proxy)
{
    $request = new GetAdGroupCriterionsByAdGroupIdRequest();
    $response = null; // GetAdGroupCriterionsByAdGroupIdResponse

    // Set the request information.

    $request->AccountId = $accountId;
    $request->AdGroupId = $adGroupId;
    $request->CriterionTypeFilter = array( CriterionType::Product );

    try
    {
        $response = $proxy->GetService()->GetAdGroupCriterionsByAdGroupId($request);
    }
    catch (SoapFault $e)
    {
        print "GetAdGroupCriterionsByIds failed.\n";

        if (isset($e->detail->ApiFaultDetail))
        {
            print "ApiFaultDetail exception encountered\n";
            print "Tracking ID: ".$e->detail->ApiFaultDetail->TrackingId."\n";

            // Process any operation errors.

            if (!empty($e->detail->ApiFaultDetail->OperationErrors))
            {
                $errors = is_array($e->detail->ApiFaultDetail->OperationErrors->OperationError)
                        ? $e->detail->ApiFaultDetail->OperationErrors->OperationError
                        : array('OperationError' => $e->detail->ApiFaultDetail->OperationErrors->OperationError);

                foreach ($errors as $error)
                {
                    switch ($error->Code)
                    {
                        case 106: //  UserIsNotAuthorized
                            print("The user is not authorized to call this operation.\n");
                            break;

                        case 1102: //  CampaignServiceInvalidAccountId
                            print("The account ID is not valid.\n");
                            break;

                        case 1201: //  CampaignServiceInvalidAdGroupId
                            print("The ad group ID is not valid.\n");
                            break;

                        case 1030: //  CampaignServiceAccountIdHasToBeSpecified
                            print("You must specify the account ID in the CustomerAccountId header element.\n");
                            break;

                        case 4115: //  CampaignServiceInvalidAdGroupCriterionCriterionTypeFilter
                            print("The criterion type filter cannot be null.\n");
                            break;

                        default:
                            printf("Error code: %s (%d)\nMessage: %s\nDetail: %s\n",
                                $error->ErrorCode, $error->Code, $error->Message, $error->Details);
                            break;
                    }
                }
            }

            // Process any batch errors.

            if (!empty($e->detail->ApiFaultDetail->BatchErrors))
            {
                $errors = is_array($e->detail->ApiFaultDetail->BatchErrors->BatchError)
                        ? $e->detail->ApiFaultDetail->BatchErrors->BatchError
                        : array('BatchError' => $e->detail->ApiFaultDetail->BatchErrors->BatchError);

                foreach ($errors as $error)
                {
                    switch ($error->Code)
                    {
                        default:
                            print "Batch error encountered for array index ".$error->Index.".\n";
                            printf("Error code: %s (%d)\nMessage: %s\nDetail: %s\n\n",
                                $error->ErrorCode, $error->Code, $error->Message, $error->Details);
                            break;
                    }
                }
            }
        }
        elseif (isset($e->detail->AdApiFaultDetail))
        {
            print "AdApiFaultDetail exception encountered\n";
            print "Tracking ID: ".$e->detail->AdApiFaultDetail->TrackingId ."\n";

            // Process any system errors.

            $errors = is_array($e->detail->AdApiFaultDetail->Errors->AdApiError)
                    ? $e->detail->AdApiFaultDetail->Errors->AdApiError
                    : array('AdApiError' => $e->detail->AdApiFaultDetail->Errors->AdApiError);

            foreach ($errors as $error)
            {
                if (105 == $error->Code) //  InvalidCredentials
                {
                    print "The specified credentials are not valid or the account is inactive.\n";
                }
                else
                {
                    printf("Error code: %s (%d)\nMessage: %s\nDetail: %s\n",
                        $error->ErrorCode, $error->Code, $error->Message, $error->Detail);
                }
            }
        }
        else
        {
            print $e->getCode()." ".$e->getMessage()."\n\n";

            // Output the last request/response.

            print "\nLast SOAP request/response:\n";
            print $proxy->GetWsdl()."\n";
            print $proxy->GetService()->__getLastRequest()."\n";
            print $proxy->GetService()->__getLastResponse()."\n";
        }

        throw new Exception("", 0, $e);
    }

    return $response->AdGroupCriterions;
}


// Updates the criterions in the ad group. Any field not set
// to null is updated.

function UpdateProductCriterion($accountId, $criterions, $proxy)
{
    $request = new UpdateAdGroupCriterionsRequest();
    $response = null; // UpdateAdGroupCriterionsResponse
    $updatedCriterions = array();

    $length = count($criterions->AdGroupCriterion);

    for ($i=0; $i < $length; $i++)
    {
        if ($criterions->AdGroupCriterion[$i]->Type === 'BiddableAdGroupCriterion')
        {
            if ($criterions->AdGroupCriterion[$i]->CriterionBid->Type === 'FixedBid')
            {
                // Increase the bid by 20 percent if the criterion's bid amount
                // is not set to null (a null bid amount indicates that the
                // criterion uses the ad group's exact-match bid value).

                if (null != $criterions->AdGroupCriterion[$i]->CriterionBid->Bid->Amount)
                {
                    $update = new BiddableAdGroupCriterion();

                    $update->Id = $criterions->AdGroupCriterion[$i]->Id;    // Required
                    $update->AdGroupId = $criterions->AdGroupCriterion[$i]->AdGroupId;  // Required

                    // Update Status if you want to pause, resume, or delete the criterion.

                    $update->Status = null;  // AdGroupCriterionStatus::Paused;

                    $fixedBid = new FixedBid();
                    $fixedBid->Bid = new Bid();
                    $fixedBid->Bid->Amount = $criterions->AdGroupCriterion[$i]->CriterionBid->Bid->Amount * 1.20;
                    $encodedBid = new SoapVar($fixedBid, SOAP_ENC_OBJECT, 'FixedBid', $proxy->GetNamespace());
                    $update->CriterionBid = $encodedBid;

                    // To remove the destination URL or parameter, set to an empty string.

                    $update->DestinationUrl = null;
                    $update->Param1 = null;
                    $update->Param2 = null;
                    $update->Param3 = null;

                    // If you don't want to update the criterion, set Criterion to null.
                    // To remove all conditions, set Conditions to an empty list. For example,

                    $update->Criterion = null;

                    $encodedCriterion = new SoapVar($update, SOAP_ENC_OBJECT, 'BiddableAdGroupCriterion', $proxy->GetNamespace());
                    $updatedCriterions[] = $encodedCriterion;
                }
            }
        }
    }

    if (0 == count($updatedCriterions))
    {
        return; // Nothing to update
    }

    // Set the request information.

    $request->AccountId = $accountId;
    $request->AdGroupCriterions = $updatedCriterions;

    try
    {
        $response = $proxy->GetService()->UpdateAdGroupCriterions($request);
    }
    catch (SoapFault $e)
    {
        print "UpdateAdGroupCriterions failed.\n";

        if (isset($e->detail->ApiFaultDetail))
        {
            print "ApiFaultDetail exception encountered\n";
            print "Tracking ID: ".$e->detail->ApiFaultDetail->TrackingId."\n";

            // Process any operation errors.

            if (!empty($e->detail->ApiFaultDetail->OperationErrors))
            {
                $errors = is_array($e->detail->ApiFaultDetail->OperationErrors->OperationError)
                        ? $e->detail->ApiFaultDetail->OperationErrors->OperationError
                        : array('OperationError' => $e->detail->ApiFaultDetail->OperationErrors->OperationError);

                foreach ($errors as $error)
                {
                    switch ($error->Code)
                    {
                        case 1030: //  CampaignServiceAccountIdHasToBeSpecified
                            print("You must specify the account ID in the CustomerAccountId header element.\n");
                            break;

                        case 3863: // CampaignServiceProductAdExtensionPilotNotEnabledForCustomer
                            print("To add ad group criterions, the customer " .
                                "must be a member of the Product Ads pilot program.\n");
                            break;

                        case 4104: // CampaignServiceAdGroupCriterionsNullOrEmpty
                            print("To list of ad group criterions cannot be null or empty.\n");
                            break;

                        default:
                            printf("Error code: %s (%d)\nMessage: %s\nDetail: %s\n",
                                $error->ErrorCode, $error->Code, $error->Message, $error->Details);
                            break;
                    }
                }
            }

            // Process any batch errors.

            if (!empty($e->detail->ApiFaultDetail->BatchErrors))
            {
                $errors = is_array($e->detail->ApiFaultDetail->BatchErrors->BatchError)
                        ? $e->detail->ApiFaultDetail->BatchErrors->BatchError
                        : array('BatchError' => $e->detail->ApiFaultDetail->BatchErrors->BatchError);

                foreach ($errors as $error)
                {
                    switch ($error->Code)
                    {
                        case 1515: // CampaignServiceBidAmountsLessThanFloorPrice
                            printf("The bid value of ad group criterion #%d is " .
                                "less than the minimum allowed bid value.\n\n",
                                $error->Index);
                            break;

                        case 1516: // CampaignServiceBidAmountsGreaterThanCeilingPrice
                            printf("The bid value of ad group criterion #%d exceeds " .
                                "the maximum allowed bid value.\n\n",
                                $error->Index);
                            break;

                        case 3869: // CampaignServiceProductAdExtensionOperandIsInvalid
                            printf("Product operand #%s of ad group criterion #%d " .
                                "is not valid.\n\n",
                                $error->Details,
                                $error->Index);
                            break;

                        case 3870: // CampaignServiceProductAdExtensionAttributeIsInvalid
                            printf("Product attribute #%s of ad group criterion #%d " .
                                "is not valid.\n\n",
                                $error->Details,
                                $error->Index);
                            break;

                        case 3872: // CampaignServiceProductConditionDuplicateOperand
                            printf("Ad group criterion #%s contains duplicate product operands. " .
                                "Product operand #%d is a duplicate.\n\n",
                                $error->Details,
                                $error->Index);
                            break;

                        case 4108: // CampaignServiceAdGroupCriterionInvalidBidType
                            printf("The bid of ad group criterion #%d is null or " .
                                "is of the wrong type.\n\n",
                                $error->Index);
                            break;

                        case 4109: // CampaignServiceAdGroupCriterionInvalidBidValue
                            printf("The bid value of ad group criterion #%d is not valid.\n\n",
                                $error->Index);
                            break;

                        case 4113: // CampaignServiceProductAdGroupCriterionTooManyConditions
                            printf("The list of product conditions of ad group " .
                                "criterion #%d is too long.\n\n",
                                $error->Index);
                            break;

                        default:
                            print "Batch error encountered for array index ".$error->Index.".\n";
                            printf("Error code: %s (%d)\nMessage: %s\nDetail: %s\n\n",
                                $error->ErrorCode, $error->Code, $error->Message, $error->Details);
                            break;
                    }
                }
            }
        }
        elseif (isset($e->detail->AdApiFaultDetail))
        {
            print "AdApiFaultDetail exception encountered\n";
            print "Tracking ID: ".$e->detail->AdApiFaultDetail->TrackingId ."\n";

            // Process any system errors.

            $errors = is_array($e->detail->AdApiFaultDetail->Errors->AdApiError)
                    ? $e->detail->AdApiFaultDetail->Errors->AdApiError
                    : array('AdApiError' => $e->detail->AdApiFaultDetail->Errors->AdApiError);

            foreach ($errors as $error)
            {
                if (105 == $error->Code) //  InvalidCredentials
                {
                    print "The specified credentials are not valid or the account is inactive.\n";
                }
                else
                {
                    printf("Error code: %s (%d)\nMessage: %s\nDetail: %s\n",
                        $error->ErrorCode, $error->Code, $error->Message, $error->Detail);
                }
            }
        }
        else
        {
            print $e->getCode()." ".$e->getMessage()."\n\n";

            // Output the last request/response.

            print "\nLast SOAP request/response:\n";
            print $proxy->GetWsdl()."\n";
            print $proxy->GetService()->__getLastRequest()."\n";
            print $proxy->GetService()->__getLastResponse()."\n";
        }

        throw new Exception("", 0, $e);
    }
}

// Prints the details of the criterion.

function PrintAdGroupCriterions($criterionIds, $criterions)
{
    $i = 0;

    foreach ($criterions->AdGroupCriterion as $adGroupCriterion)
    {
        if (null != $adGroupCriterion)
        {
            if ($adGroupCriterion->Type === 'BiddableAdGroupCriterion')
            {
                print("Biddable criterion ID: " . $adGroupCriterion->Id . "\n");

                if ($adGroupCriterion->CriterionBid->Type === 'FixedBid')
                {
                    if (null == $adGroupCriterion->CriterionBid->Bid->Amount)
                    {
                        print("  Bid amount: Uses the ad group's exact-match bid value\n");
                    }
                    else
                    {
                        printf("  Bid amount: %.2f\n",$adGroupCriterion->CriterionBid->Bid->Amount);
                    }
                }

                printf("  Destination URL: %s\n", $adGroupCriterion->DestinationUrl);
                printf("  Param1: %s\n", $adGroupCriterion->Param1);
                printf("  Param2: %s\n", $adGroupCriterion->Param2);
                printf("  Param3: %s\n", $adGroupCriterion->Param3);
                printf("  Status: %s\n", $adGroupCriterion->Status);
                printf("  Editorial status: %s\n", $adGroupCriterion->EditorialStatus);

                if ($adGroupCriterion->Criterion->Type === 'Product')
                {
                    print("  Product conditions: ");

                    if (isset($adGroupCriterion->Criterion->Conditions->ProductCondition))
                    {
                        $length = count($adGroupCriterion->Criterion->Conditions->ProductCondition);

                        for ($j = 0; $j < $length; $j++)
                        {
                            printf("%s=%s%s", $adGroupCriterion->Criterion->Conditions->ProductCondition[$j]->Operand,
                                $adGroupCriterion->Criterion->Conditions->ProductCondition[$j]->Attribute,
                                ($j + 1 < $length) ? " AND " : "\n\n");
                        }
                    }
                    else
                    {
                        print("No product filter applied.\n\n");
                    }
                }
            }
        }
        else
        {
            printf("Ad group criterion %d was not found.\n\n", $criterionIds[$i]);
        }

        $i++;
    }
}


// Callbacks referenced in the SoapClient options.

// Converts long types found in SOAP responses to string types in PHP.

function from_long_xml($xmlFragmentString)
{
    return (string)strip_tags($xmlFragmentString);
}

// Converts PHP string types to long types in SOAP requests.

function to_long_xml($longVal)
{
    return '<long>' . $longVal . '</long>';
}

// Define the proxy class for the Campaign Management service.

Class ClientProxy
{
    private $username;
    private $password;
    private $developerToken;
    private $wsdlUrl;
    private $accountId;
    private $customerId;
    private $service;
    private $namespace;

    public function __construct($username, $password, $token, $accountId, $customerId, $wsdl)
    {
        $this->username = $username;
        $this->password = $password;
        $this->developerToken = $token;
        $this->accountId = $accountId;
        $this->customerId = $customerId;
        $this->wsdlUrl = $wsdl;
        $this->service = $this->GetProxy($wsdl);
    }

    public function GetAccountId() { return $this->accountId; }
    public function GetCustomerId() { return $this->customerId; }
    public function GetService() { return $this->service; }
    public function GetNamespace() { return $this->namespace; }
    public function GetWsdl() { return $this->wsdlUrl; }

    // This function gets the namespace from the WSDL, so you do
    // not have to hardcode it in the client.

    private function GetServiceNamespace($url)
    {
        $doc = new DOMDocument;
        $doc->Load($url);

        $xpath = new DOMXPath($doc);
        $query = "/*/@targetNamespace";

        $attrs = $xpath->query($query);

        // The query will return only one node in the node list.

        foreach($attrs as $attr)
        {
            $namespace = $attr->value;
        }

        return $namespace;
    }

    private function GetProxy($wsdl)
    {
        $this->namespace = $this->GetServiceNamespace($wsdl);

        // Define the SOAP headers. Customer ID is required
        // to get editorial reasons.

        $headers = array();

        $headers[] = new SoapHeader(
            $this->namespace,
            'CustomerAccountId',
            $this->accountId
            );

        $headers[] = new SoapHeader(
            $this->namespace,
            'CustomerId',
            $this->customerId
            );

        $headers[] = new SoapHeader(
            $this->namespace,
            'DeveloperToken',
            $this->developerToken
            );

        $headers[] = new SoapHeader(
            $this->namespace,
            'UserName',
            $this->username
            );

        $headers[] = new SoapHeader(
            $this->namespace,
            'Password',
            $this->password
            );

        // By default, PHP does not return single item arrays as an array type.
        // To force PHP to always return an array for an array type in the
        // response, specify the SOAP_SINGLE_ELEMENT_ARRAYS feature.

        $options = array(
            'trace' => TRUE,
            'exceptions' => TRUE,
            'features' => SOAP_SINGLE_ELEMENT_ARRAYS,

            // Map long type to string type. For details, see
            // from_long_xml and to_long_xml callbacks.

            'typemap' => array(
                array(
                'type_ns' => 'http://www.w3.org/2001/XMLSchema',
                'type_name' => 'long',
                'to_xml' => 'to_long_xml',
                'from_xml' => 'from_long_xml'
                ),
            )
        );

        $proxy = @new SOAPClient($this->wsdlUrl, $options);

        $proxy->__setSoapHeaders($headers);

        return $proxy;
    }
}

// Defines the Campaign Management value sets used in this example.

final class AdGroupCriterionStatus
{
    const Active = 'Active';
    const Paused = 'Paused';
    const Deleted = 'Deleted';
}

final class CriterionType
{
    const Product = 'Product';
}

final class AdGroupCriterionEditorialStatus
{
    const Active = 'Active';
    const Disapproved = 'Disapproved';
    const Inactive = 'Inactive';
}


// Defines the Campaign Management error objects that the operations can return.

final class AdApiError
{
    public $Code;
    public $Detail;
    public $ErrorCode;
    public $Message;
}

final class BatchError
{
    public $Code;
    public $Details;
    public $ErrorCode;
    public $Index;
    public $Message;
}

final class EditorialError
{
    public $Appealable;
    public $Code;
    public $DisapprovedText;
    public $ErrorCode;
    public $Index;
    public $Message;
    public $PublisherCountry;
}

final class OperationError
{
    public $Code;
    public $Details;
    public $ErrorCode;
    public $Message;
}

class ApplicationFault
{
    public $TrackingId;
}

final class ApiFaultDetail extends ApplicationFault
{
    public $BatchErrors;
    public $OperationErrors;
}

final class AdApiFaultDetail extends ApplicationFault
{
    public $Errors;
}

final class EditorialApiFaultDetail extends ApplicationFault
{
    public $BatchErrors;
    public $EditorialErrors;
    public $OperationErrors;
}

// Defines the Campaign Management data objects used in this example.

class Criterion
{
    public $Type;
}

class AdGroupCriterion
{
    public $AdGroupId;
    public $Criterion;
    public $Id;
    public $Status;
    public $Type;
}

final class Bid
{
    public $Amount;
}

final class ProductCondition
{
    public $Attribute;
    public $Operand;
}

final class Product extends Criterion
{
    public $Conditions;
}

class CriterionBid
{
    public $Type;
}

final class BiddableAdGroupCriterion extends AdGroupCriterion
{
    public $CriterionBid;
    public $DestinationUrl;
    public $EditorialStatus;
    public $Param1;
    public $Param2;
    public $Param3;
}

final class FixedBid extends CriterionBid
{
    public $Bid;
}

class Ad
{
    public $EditorialStatus;
    public $Id;
    public $Status;
    public $Type;
}

final class ProductAd extends Ad
{
    public $PromotionalText;
}

class AdExtension2
{
    public $Id;
    public $Status;
    public $Type;
    public $Version;
}

final class AdExtensionIdentity
{
    public $Id;
    public $Version;
}

final class ProductConditionCollection
{
    public $Conditions;
}

final class ProductAdExtension extends AdExtension2
{
    public $Name;
    public $ProductCollectionId;
    public $ProductCollectionName;
    public $ProductSelection;
}

final class AdExtensionIdToCampaignIdAssociation
{
    public $AdExtensionId;
    public $CampaignId;
}

// Defines the request and response messages of the Campaign Management
// operations used in this example.

final class AddAdsRequest
{
    public $AdGroupId;
    public $Ads;
}

final class AddAdsResponse
{
    public $AdIds;
}

final class GetAdGroupCriterionsByIdsRequest
{
    public $AccountId;
    public $AdGroupCriterionIds;
}

final class GetAdGroupCriterionsByIdsResponse
{
    public $AdGroupCriterions;
}

final class GetAdGroupCriterionsByAdGroupIdRequest
{
    public $AccountId;
    public $AdGroupId;
    public $CriterionTypeFilter;
}

final class GetAdGroupCriterionsByAdGroupIdResponse
{
    public $AdGroupCriterions;
}

final class AddAdGroupCriterionsRequest
{
    public $AccountId;
    public $AdGroupCriterions;
}

final class AddAdGroupCriterionsResponse
{
    public $AdGroupCriterionIds;
}

final class UpdateAdGroupCriterionsRequest
{
    public $AccountId;
    public $AdGroupCriterions;
}

final class UpdateAdGroupCriterionsResponse
{
}

final class DeleteAdGroupCriterionsRequest
{
    public $AccountId;
    public $AdGroupCriterionIds;
    public $AdGroupId;
}

final class DeleteAdGroupCriterionsResponse
{
}

final class AddAdExtensionsRequest
{
    public $AccountId;
    public $AdExtensions;
}

final class AddAdExtensionsResponse
{
    public $AdExtensionIdentities;
}

final class SetAdExtensionsToCampaignsRequest
{
    public $AccountId;
    public $AdExtensionIdToCampaignIdAssociations;
}

final class SetAdExtensionsToCampaignsResponse
{
}

?>

Community Additions

Show:
© 2014 Microsoft