title: PHP AdWords API v201809 - How to get city name using LocationCriterionService from GEO_PERFORMANCE_REPORT?
body: <p>Instead of pulling a <code>CRITERIA_PERFORMANCE_REPORT</code>, I'm pulling a <code>GEO_PERFORMANCE_REPORT</code> using this example: <a href="https://developers.google.com/adwords/api/docs/samples/php/reporting#download-a-criteria-performance-report-with-awql" rel="nofollow noreferrer">https://developers.google.com/adwords/api/docs/samples/php/reporting#download-a-criteria-performance-report-with-awql</a></p>
  
  <p>I'm pulling the <code>CityCriteriaId</code> attribute for each result from this API report. </p>
  
  <p>I'm looking to use the <code>LocationCriterionService</code> to figure out what the name of the city is based on the IDs that are returned but stuck on the most efficient way to craft this query. Here's what I have so far:</p>
  
  <p><strong>Dependencies:</strong></p>
  
  <pre><code>namespace Google\AdsApi\Examples\AdWords\v201809\Reporting;
  namespace Google\AdsApi\Examples\AdWords\v201809\Targeting;
  
  require __DIR__ . '/vendor/autoload.php';
  
  // For all the services/methods necessary from the Reporting namespace
  use Google\AdsApi\AdWords\AdWordsSession;
  use Google\AdsApi\AdWords\AdWordsSessionBuilder;
  use Google\AdsApi\AdWords\Query\v201809\ReportQueryBuilder;
  use Google\AdsApi\AdWords\Reporting\v201809\DownloadFormat;
  use Google\AdsApi\AdWords\Reporting\v201809\ReportDefinitionDateRangeType;
  use Google\AdsApi\AdWords\Reporting\v201809\ReportDownloader;
  use Google\AdsApi\AdWords\ReportSettingsBuilder;
  use Google\AdsApi\AdWords\v201809\cm\DateRange;
  use Google\AdsApi\AdWords\v201809\cm\ReportDefinitionReportType;
  use Google\AdsApi\Common\OAuth2TokenBuilder;
  
  // For all the services/methods necessary for the LocationCriterionService
  // and Targeting namespace
  use Google\AdsApi\AdWords\AdWordsServices;
  use Google\AdsApi\AdWords\v201809\cm\LocationCriterionService;
  use Google\AdsApi\AdWords\v201809\cm\Predicate;
  use Google\AdsApi\AdWords\v201809\cm\PredicateOperator;
  use Google\AdsApi\AdWords\v201809\cm\Selector;
  </code></pre>
  
  <p><strong>runExample:</strong> Here's the report code I have (this is all in it's own class):</p>
  
  <pre><code>public static function runExample(AdWordsServices $adS, AdWordsSession $session, $reportF)
  {
      $query = (new ReportQueryBuilder())
          -&gt;select([
              'CityCriteriaId',
              'Clicks'
          ])
          -&gt;from(ReportDefinitionReportType::GEO_PERFORMANCE_REPORT)
          -&gt;duringDateRange(ReportDefinitionDateRangeType::LAST_7_DAYS)
          -&gt;build();
  
      $reportDownloader = new ReportDownloader($session);
      $reportSettingsOverride = (new ReportSettingsBuilder())
          -&gt;includeZeroImpressions(false)
          -&gt;build();
      $reportDownloadResult = $reportDownloader-&gt;downloadReportWithAwql(
          sprintf('%s', $query),
          $reportF,
          $reportSettingsOverride
      );
  
      $reportResult = $reportDownloadResult-&gt;getAsString();
      $xml = simplexml_load_string($reportResult);
      $data = json_decode(json_encode((array)$xml), TRUE);
  
      $locationIDs = [];
      $results = $data['table']['row']['@attributes']['city'];
      foreach ($results as $cityID) {
          array_push($locationIDs, $cityID);
      }
  
      // Here's where I don't know what to do...
      // But any and all code for the LocationCriterionService would be done here
  
  }
  </code></pre>
  
  <p><strong>Main function:</strong> (taken from the example in the URL above)</p>
  
  <pre><code>public static function main()
  {
      $oAuth2Credential = (new OAuth2TokenBuilder())-&gt;fromFile()-&gt;build();
  
      $session = (new AdWordsSessionBuilder())
          -&gt;fromFile()
          -&gt;withOAuth2Credential($oAuth2Credential)
          -&gt;build();
  
      self::runExample(new AdWordsServices(), $session, DownloadFormat::XML);
  }
  </code></pre>
  
  <p>Any help would be appreciated with regards to what I should place inside of that <code>foreach</code> loop that loops through the City IDs from the report result.</p>
  
  <p><strong>PLEASE NOTE:</strong> I realize that the other way is to store the 100,000 some records (of the .csv Google provides to cross reference cities with their allocated IDs) in a local database and cross reference this way, but this way is preferred.</p>
  
  <p><strong>EDIT:</strong></p>
  
  <p>I started getting some progress with some additional code particular for the <code>LocationCriterionService</code> yet it yields an error because my parameter for the Predicate variable is wrong (the <code>soap</code> dll is required in your <code>php_info</code>):</p>
  
  <pre><code>$locationCriterionService = $adS-&gt;get($session, LocationCriterionService::class);
  
  $selector = new Selector();
  $selector-&gt;setFields(
      [
          'Id',
          'LocationName',
          'CanonicalName'
      ]
  );
  
  $selector-&gt;setPredicates(
      [
          new Predicate('locationid', PredicateOperator::EQUALS, $locationIDs)
      ]
  );
  
  $locationCriteria = $locationCriterionService-&gt;get($selector);
  
  if ($locationCriteria !== null) {
      foreach ($locationCriteria as $locationCriterion) {
          printf(
              "The search term '%s' returned the location '%s' of type '%s' "
              . "with ID %d, and reach %d (%s).\n",
              $locationCriterion-&gt;getSearchTerm(),
              $locationCriterion-&gt;getLocation()-&gt;getLocationName(),
              $locationCriterion-&gt;getLocation()-&gt;getDisplayType(),
              $locationCriterion-&gt;getLocation()-&gt;getId()
          );
      }
  } else {
      print "No location criteria were found.\n";
  }
  </code></pre>
  
  <p>The error is:</p>
  
  <blockquote>
    <p>Uncaught Google\AdsApi\AdWords\v201809\cm\ApiException:
    [SelectorError.INVALID_PREDICATE_FIELD_NAME @ selector;
    trigger:'locationid']</p>
  </blockquote>