Export (0) Print
Expand All

Ad Extensions in PHP

The following example shows how to add extensions to an account’s ad extension library, get extensions from the library, associate the extensions with a campaign, get the extensions that are associated with a campaign, and determine why an extension failed editorial review using the following Campaign Management service operations.

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

// You must pass the URL of the Campaign Management WSDL.

// Command line usage:
// php.exe AdExtensions wsdl
//

// 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>;

// Specify the campaign to add the extensions to.
// Specify the campaign ID as a string.

$campaignId = "<campaignidgoeshere>";

// Campaign Management WSDL passed as argument

$wsdl = $argv[1];

$ids = null;


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

    $ids = AddExtensions($accountId, $proxy);
    PrintExtensions($accountId, $ids, $proxy);
    AssociateExtensionsWithCampaign($accountId, $campaignId, $ids, $proxy);
    PrintExtensionsAssociatedWithCampaigns($accountId, array($campaignId), $proxy);
}
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 an ad extension of each type (for example, a location ad
// extension and a call ad extension) to the account's
// ad extension library.

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

    // Set the request information.

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

    // Specify site links extensions.

    $extension = new SiteLinksAdExtension();
    $extension->SiteLinks = array();

    $extension->SiteLinks[0] = new SiteLink();
    $extension->SiteLinks[0]->DestinationUrl = "AplineSkiHouse.com/WinterGloveSale";
    $extension->SiteLinks[0]->DisplayText = "Winter Glove Sale";

    $extension->SiteLinks[1] = new SiteLink();
    $extension->SiteLinks[1]->DestinationUrl = "AplineSkiHouse.com/WinterPolesSale";
    $extension->SiteLinks[1]->DisplayText = "Winter Poles Sale";

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

    // Specify call extensions.

    $extension = new CallAdExtension();
    $extension->CountryCode = "US";
    $extension->PhoneNumber = "2065550100";
    $extension->IsCallOnly = false;

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

    // Specify location extensions.

    $extension = new LocationAdExtension();
    $extension->PhoneNumber = "206-555-0100";
    $extension->CompanyName = "Alpine Ski House";
    $extension->IconMediaId = null;  // Used default map icon
    $extension->ImageMediaId = null;
    $extension->Address = new Address;
    $extension->Address->StreetAddress = "1234 Washington Place";
    $extension->Address->StreetAddress2 = "Suite 1210";
    $extension->Address->CityName = "Woodinville";
    $extension->Address->ProvinceName = "WA"; // Can contain the state name or code (i.e. WA)
    $extension->Address->CountryCode = "US";
    $extension->Address->PostalCode = "98608";

    $encodedExtension = new SoapVar($extension, SOAP_ENC_OBJECT, 'LocationAdExtension', $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 site link in the list of site links 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 3804: // CampaignServiceSiteLinkDestinationUrlNullOrEmpty
                            printf("The destination URL of site link #%s in " .
                                "extension #%d cannot be null or empty.\n\n",
                                $error->Details,
                                $error->Index);
                            break;

                        case 3805: // CampaignServiceSiteLinkDisplayTextNullOrEmpty
                            printf("The display URL of site link #%s in " .
                                "extension #%d cannot be null or empty.\n\n",
                                $error->Details,
                                $error->Index);
                            break;

                        case 3806: // CampaignServiceSiteLinkDestinationUrlTooLong
                            printf("The destination URL of site link #%s in " .
                                "extension #%d is too long.\n\n",
                                $error->Details,
                                $error->Index);
                            break;

                        case 3807: // CampaignServiceSiteLinkDisplayTextTooLong
                            printf("The display URL of site link #%s in " .
                                "extension #%d is too long.\n\n",
                                $error->Details,
                                $error->Index);
                            break;

                        case 3809: // CampaignServiceTooManySiteLinks
                            print("The list of site links contains too many items.\n\n");
                            break;

                        case 3828: // CampaignServiceAdExtensionAddressIsNull
                            printf("The address in extension #%d cannot be null.\n\n",
                                $error->Index);
                            break;

                        case 3829: // CampaignServiceAdExtensionStreetAddressNullOrEmpty
                            printf("The first line of the street address in " .
                                "extension #%d cannot be null or empty.\n\n",
                                $error->Index);
                            break;

                        case 3830: // CampaignServiceAdExtensionStreetAddressTooLong
                            printf("The first line of the street address in " .
                                "extension #%d is too long.\n\n",
                                $error->Index);
                            break;

                        case 3834: // CampaignServiceAdExtensionCityNameNullOrEmpty
                            printf("The city name in extension #%d cannot be " .
                                "null or empty.\n\n",
                                $error->Index);
                            break;

                        case 3839: // CampaignServiceAdExtensionPostalCodeNullOrEmpty
                            printf("The postal code in extension #%d cannot " .
                                "be null or empty.\n\n",
                                $error->Index);
                            break;

                        case 3842: // CampaignServiceAdExtensionCountryCodeNullOrEmpty
                            printf("The country code in extension #%d cannot " .
                                "be null or empty.\n\n",
                                $error->Index);
                            break;

                        case 3844: // CampaignServiceAdExtensionCountryCodeInvalid
                            printf("The country code in extension #%d is not valid.\n\n",
                                $error->Index);
                            break;

                        case 3847: // CampaignServiceAdExtensionCompanyNameNullOrEmpty
                            printf("The compangy name in extension #%d cannot " .
                                "be null or empty.\n\n",
                                $error->Index);
                            break;

                        case 3850: // CampaignServiceAdExtensionPhoneNumberTooLong
                            printf("The phone number in extension #%d is too long.\n\n",
                                $error->Index);
                            break;

                        case 3851: // CampaignServiceAdExtensionPhoneNumberInvalid
                            printf("The phone number in extension #%d is not valid.\n\n",
                                $error->Index);
                            break;

                        case 3852: // CampaignServiceAdExtensionIconMediaIdInvalid
                            printf("The icon in extension #%d was not " .
                                "found in the account’s media library or is not " .
                                 "one of the predefined icons.\n\n",
                                $error->Index);
                            break;

                        case 3853: // CampaignServiceAdExtensionIconTooLarge
                            printf("The width and height of the icon in " .
                                "extension #%d is greater than the maximum allowed.\n\n",
                                $error->Index);
                            break;

                        case 3854: // CampaignServiceAdExtensionImageMediaIdInvalid
                            printf("The image in extension #%d was not found " .
                                "in the account’s media library.\n\n",
                                $error->Index);
                            break;

                        case 3855: // CampaignServiceAdExtensionImageTooLarge
                            printf("The width and height of the image in " .
                                "extension #%d is greater than the maximum allowed.\n\n",
                                $error->Index);
                            break;

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

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

                        case 3859: // CampaignServiceAdExtensionProvinceCodeInvalid
                            printf("The province code in extension #%d " .
                                "is not valid.\n\n",
                                $error->Index);
                            break;

                        case 3860: // CampaignServiceAdExtensionProvinceCodeRequiredIfProvinceNameEmpty
                            printf("The province code in extension #%d is " .
                                "required if the province name is empty.\n\n",
                                $error->Index);
                            break;

                        case 3861: // CampaignServiceAdExtensionPhoneNumberNullOrEmpty
                            printf("The phone number in extension #%d " .
                                "cannot be null or empty.\n\n",
                                $error->Index);
                            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;
}

// Gets the specified ad extensions from the account's library
// and prints their contents.

function PrintExtensions($accountId, $ids, $proxy)
{
    $request = new GetAdExtensionsByIdsRequest();
    $response = null;  // GetAdExtensionsByIdsResponse
    $i = 0;

    // Set the request information.

    $request->AccountId = $accountId;
    $request->AdExtensionIds = $ids;
    $request->AdExtensionType = array(
        AdExtensionsTypeFilter::SiteLinksAdExtension,
        AdExtensionsTypeFilter::CallAdExtension,
        AdExtensionsTypeFilter::LocationAdExtension);

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

        foreach ($response->AdExtensions->AdExtension2 as $extension)
        {
            if (null == $extension)
            {
                printf("Extension ID %s is not a valid ID or the extension " .
                    "does not match the request type.\n",
                    $ids[$i]);
            }
            else
            {
                print("Ad extension ID: " . $extension->Id . "\n");
                print("Ad extension Type: " . $extension->Type . "\n");

                if ($extension->Type === "SiteLinksAdExtension")
                {
                    foreach ($extension->SiteLinks->SiteLink as $siteLink)
                    {
                        print("  Display URL: " . $siteLink->DisplayText . "\n");
                        print("  Destination URL: " . $siteLink->DestinationUrl . "\n");
                        print("\n");
                    }
                }
                else if ($extension->Type === "CallAdExtension")
                {
                    print("Phone number: " . $extension->PhoneNumber . "\n");
                    print("Country: " . $extension->CountryCode . "\n");
                    printf("Is only clickable item: %s\n",
                        (true == $extension->IsCallOnly) ? "true" : "false");
                    print("\n");
                }
                else if ($extension->Type === "LocationAdExtension")
                {
                    // Ads will not include the location extension until the business' coordinates 
                    // (longitude and latitude) are determined using the business' address. The GeoCodeStatus
                    // field indicates the progress. It can take from seconds to minutes to determine
                    // the coordinates.

                    print("Company name: " . $extension->CompanyName . "\n");
                    print("Phone number: " . $extension->PhoneNumber . "\n");
                    print("Street: " . $extension->Address->StreetAddress . "\n");
                    print("City: " . $extension->Address->CityName . "\n");
                    print("State: " . $extension->Address->ProvinceName . "\n");
                    print("Country: " . $extension->Address->CountryCode . "\n");
                    print("Zip code: " . $extension->Address->PostalCode . "\n");
                    print("Business coordinates determined?: " . $extension->GeoCodeStatus . "\n");
                    print("Map icon ID: " . $extension->IconMediaId . "\n");
                    print("Business image ID: " . $extension->ImageMediaId . "\n");
                    print("\n");
                }
                else
                {
                    print("  Unknown extension type\n");
                }
            }

            print("\n");
            $i++;
        }
    }
    catch (SoapFault $e)
    {
        // Log this fault.

        print("GetAdExtensionsByIds 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 3814: //  CampaignServiceInvalidAdExtensionTypeFilter
                            print("The ad extension type filter is null " .
                                "or is not one of the allowed extension types.\n");
                            break;

                        case 3815: //  CampaignServiceAdExtensionIdArrayShouldNotBeNullOrEmpty
                            print("The list of extension IDs cannot be null or empty.\n");
                            break;

                        case 3816: //  CampaignServiceAdExtensionIdsArrayExceedsLimit
                            print("The list of ad extension IDs is too long.\n");
                            break;

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

                        case 3857: //  CampaignServiceCallAdExtensionPilotNotEnabledForCustomer
                            print("To get call extensions, the customer must be a " .
                                "member of the call ad extensions v2 pilot program.\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 3817: //  CampaignServiceDuplicateInAdExtensionIds
                            printf("The list of extension IDs contains duplicates. " .
                                "ID %s is a duplicate.\n\n",
                                $request->AdExtensionIds[$error->Index]);
                            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);
    }
}

// Associates one or more extensions with a campaign.

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

    if (0 == $IdsCount)
    {
        return;
    }

    // Loop through the list of extension IDs and build
    // the association objects.

    $associations = array();

    for ($i = 0; $i < $IdsCount; $i++)
    {
        $associations[$i] = new AdExtensionIdToCampaignIdAssociation();
        $associations[$i]->AdExtensionId = $extensionIds[$i];
        $associations[$i]->CampaignId = $campaignId;
    };

    // 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);
    }
}

// Gets the extensions associated with the specified campaigns
// and print the extensions ID, type, and editorial status.

function PrintExtensionsAssociatedWithCampaigns($accountId, $campaignIds, $proxy)
{
    $request = new GetAdExtensionsByCampaignIdsRequest();
    $response = null; // GetAdExtensionsByCampaignIdsResponse
    $editorialCollection = null;
    $i = 0;

    // Set the request information.

    $request->AccountId = $accountId;
    $request->CampaignIds = $campaignIds;
    $request->AdExtensionType = array(
        AdExtensionsTypeFilter::SiteLinksAdExtension,
        AdExtensionsTypeFilter::CallAdExtension,
        AdExtensionsTypeFilter::LocationAdExtension
        );

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

        // Loop through the results for each campaign.

        // Force into an array for cases where single campaign was specified and
        // it was not valid.

        $collection = is_array($response->CampaignAdExtensionCollection->CampaignAdExtensionCollection)
                ? $response->CampaignAdExtensionCollection->CampaignAdExtensionCollection
                : array('CampaignAdExtensionCollection' => $response->CampaignAdExtensionCollection->CampaignAdExtensionCollection);

        foreach ($collection as $campaign)
        {
            if (null == $campaign)
            {
                printf("Campaign ID %s is not valid.\n\n", $campaignIds[$i]);
            }
            else
            {
                // If the campaign contains extensions of the specified type...

                if (isset($campaign->CampaignAdExtensions->CampaignAdExtension))
                {
                    printf("Ad extensions associated with campaign ID %s:\n\n",
                            $campaign->CampaignAdExtensions->CampaignAdExtension[0]->CampaignId);

                    foreach ($campaign->CampaignAdExtensions->CampaignAdExtension as $extension)
                    {
                        print("Ad extension ID: " . $extension->AdExtension->Id . "\n");
                        print("Ad extension Type: " . $extension->AdExtension->Type . "\n");
                        printf("Ad extension Editorial Status: %s\n",
                            ($extension->EditorialStatus == CampaignAdExtensionEditorialStatus::Inactive) ?
                                "Under review" : $extension->EditorialStatus
                            );

                        // If the extension failed editorial review, find out why and which
                        // publisher countries were affected.

                        if ($extension->EditorialStatus == CampaignAdExtensionEditorialStatus::ActiveLimited ||
                            $extension->EditorialStatus == CampaignAdExtensionEditorialStatus::Disapproved)
                        {
                            $editorialCollection = GetEditorialReasons(
                                $accountId,
                                $campaign->CampaignAdExtensions->CampaignAdExtension[0]->CampaignId,
                                $extension->AdExtension->Id,
                                $extension->AdExtension->Type,
                                $proxy);

                            foreach ($editorialCollection->AdExtensionEditorialReasonCollection[0]->Reasons->AdExtensionEditorialReason as $editorialReason)
                            {
                                print("  Reason code: " . $editorialReason->ReasonCode . "\n");
                                print("  Term : " . $editorialReason->Term . "\n");
                                print("  Location : " . $editorialReason->Location . "\n");
                                print("  Publisher countries: ");

                                $j = 1;
                                $length = count($editorialReason->PublisherCountries->string);
                                foreach ($editorialReason->PublisherCountries->string as $country)
                                {
                                    printf("%s%s", $country, ($j++ < $length) ? ", " : "\n");
                                }
                            }
                        }

                        print("\n");
                    }
                }
                else
                {
                    printf("Campaign ID %s does not contain ad extensions " .
                        "that match the specified extension types.\n\n",
                        $campaignIds[$i]);
                }
            }

            $i++;
        }
    }
    catch (SoapFault $e)
    {
        // Log this fault.

        print("GetAdExtensionsByCampaignIds 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 1118: //  CampaignServiceCampaignIdsArrayShouldNotBeNullOrEmpty
                            print("The list of campaign IDs cannot be null or empty.\n");
                            break;

                        case 1119: //  CampaignServiceCampaignIdsArrayExceedsLimit
                            print("The list of campaign IDs is too long.\n");
                            break;

                        case 3814: //  CampaignServiceInvalidAdExtensionTypeFilter
                            print("The ad extension type filter is null " .
                                "or is not one of the allowed extension types.\n");
                            break;

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

                        case 3857: //  CampaignServiceCallAdExtensionPilotNotEnabledForCustomer
                            print("To call this operation, the customer must be a " .
                                "member of the call ad extensions v2 pilot program.\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 1107: //  CampaignServiceDuplicateCampaignIds
                            printf("The list of campaign IDs contains duplicates. " .
                                "ID %s is a duplicate.\n\n",
                                $request->CampaignIds[$error->Index]);
                            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);
    }
}

// Gets the reasons why the specified extension failed editorial
// review. The review is performed in the context of the campaign.

function GetEditorialReasons($accountId, $campaignId, $extensionId, $extensionType, $proxy)
{
    $request = new GetAdExtensionsEditorialReasonsByCampaignIdsRequest();
    $response = null; // GetAdExtensionsEditorialReasonsByCampaignIdsResponse

    // Specify the extension to campaign association.

    $associations = array();
    $associations[0] = new AdExtensionIdToCampaignIdAssociation();
    $associations[0]->AdExtensionId = $extensionId;
    $associations[0]->CampaignId = $campaignId;

    // Set the request information.

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

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

        print("GetAdExtensionsByIds 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 1029: //  CampaignServiceCustomerIdHasToBeSpecified.
                            print("The customer ID header element cannot be null or empty.\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: //  CampaignServiceAdExtensionIdToCampaignIdAssociationArrayShouldNotBeNullOrEmpty
                            print("The list of ad extension to campaign " .
                                "associations cannot be null or empty.\n");
                            break;

                        case 3811: //  CampaignServiceAdExtensionIdToCampaignIdAssociationArrayLimitExceeded
                            print("The list of ad extension to campaign " .
                                "associations is too long.\n");
                            break;

                        case 3814: //  CampaignServiceInvalidAdExtensionTypeFilter
                            print("The ad extension type filter is null " .
                                "or is not one of the allowed extension types.\n");
                            break;

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

                        case 3857: //  CampaignServiceCallAdExtensionPilotNotEnabledForCustomer
                            print("To call this operation, the customer must be a " .
                                "member of the call ad extensions pilot program.\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)
                    {
                        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 $response->EditorialReasons;
}

// 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 ad extension operations.

final class AdExtensionStatus
{
    const Active = 'Active';
    const Deleted = 'Deleted';
}

final class AdExtensionsTypeFilter
{
    const SiteLinksAdExtension = 'SiteLinksAdExtension';
    const LocationAdExtension = 'LocationAdExtension';
    const CallAdExtension = 'CallAdExtension';
}

final class CampaignAdExtensionEditorialStatus
{
    const Active = 'Active';
    const Disapproved = 'Disapproved';
    const Inactive = 'Inactive';
    const ActiveLimited = 'ActiveLimited';
}

final class ImageType
{
    const Image = 'Image';
    const Icon = 'Icon';
}


// 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 ad extension operations.

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

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

final class CampaignAdExtension
{
    public $AdExtension;
    public $CampaignId;
    public $EditorialStatus;
}

final class CampaignAdExtensionCollection
{
    public $CampaignAdExtensions;
}

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

final class AdExtensionEditorialReason
{
    public $Location;
    public $PublisherCountries;
    public $ReasonCode;
    public $Term;
}

final class AdExtensionEditorialReasonCollection
{
    public $AdExtensionId;
    public $Reasons;
}

final class CallAdExtension extends AdExtension2
{
    public $CountryCode;
    public $IsCallOnly;
    public $PhoneNumber;
}

final class Address
{
    public $CityName;
    public $CountryCode;
    public $PostalCode;
    public $ProvinceCode;
    public $ProvinceName;
    public $StreetAddress;
    public $StreetAddress2;
}

final class GeoPoint
{
    public $LatitudeInMicroDegrees;
    public $LongitudeInMicroDegrees;
}

final class LocationAdExtension extends AdExtension2
{
    public $Address;
    public $CompanyName;
    public $GeoCodeStatus;
    public $GeoPoint;
    public $IconMediaId;
    public $ImageMediaId;
    public $PhoneNumber;
}

final class SiteLink
{
    public $DestinationUrl;
    public $DisplayText;
}

final class SiteLinksAdExtension extends AdExtension2
{
    public $SiteLinks;
}


// Defines the Campaign Management operations used to manage ad extensions.

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

final class AddAdExtensionsResponse
{
    public $AdExtensionIdentities;
}

final class DeleteAdExtensionsRequest
{
    public $AccountId;
    public $AdExtensionIds;
}

final class DeleteAdExtensionsResponse
{
}

final class GetAdExtensionsByCampaignIdsRequest
{
    public $AccountId;
    public $CampaignIds;
    public $AdExtensionType;
}

final class GetAdExtensionsByCampaignIdsResponse
{
    public $CampaignAdExtensionCollection;
}

final class GetAdExtensionsByIdsRequest
{
    public $AccountId;
    public $AdExtensionIds;
    public $AdExtensionType;
}

final class GetAdExtensionsByIdsResponse
{
    public $AdExtensions;
}

final class GetAdExtensionsEditorialReasonsByCampaignIdsRequest
{
    public $AccountId;
    public $AdExtensionIdToCampaignIdAssociations;
    public $AdExtensionType;
}

final class GetAdExtensionsEditorialReasonsByCampaignIdsResponse
{
    public $EditorialReasons;
}

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

final class SetAdExtensionsToCampaignsResponse
{
}

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

final class DeleteAdExtensionsFromCampaignsResponse
{
}

final class AddImageRequest
{
    public $AccountId;
    public $Data;
    public $Type;
}

final class AddImageResponse
{
    public $MediaId;
}

final class GetImageByIdRequest
{
    public $AccountId;
    public $MediaId;
}

final class GetImageByIdResponse
{
    public $Data;
}

?>

Community Additions

Show:
© 2014 Microsoft