public function getKeywords($callback = null) {
$user = $this->getUser();
$adGroupCriterionService = $user->GetService('AdGroupCriterionService', ADWORDS_VERSION);
$awqlArray = [
"SELECT Id, KeywordText, KeywordMatchType, AdGroupId, Status, CpcBid where CriteriaType = KEYWORD and CampaignId = %s LIMIT %d,%d",
"SELECT Id, KeywordText, KeywordMatchType, AdGroupId, Status, CpcBid where CriteriaType = KEYWORD and CampaignId = %s and Status = REMOVED LIMIT %d,%d"
];
$adGroupCriterions = array();
$campaigns = Campaign::find()->all(); # must query by campaign because there are > 100,000 ads. Prevent error: SelectorError.START_INDEX_IS_TOO_HIGH
foreach ($campaigns as $campaign) {
echo "Getting keywords for campaign $campaign->name\n";
foreach ($awqlArray as $awql) {
$offset = 0;
do {
# must use %s because Google ids are long ints and %d/%u would truncate/corrupt the values
$pageQuery = sprintf($awql, $campaign->google_id, $offset, AdWordsConstants::RECOMMENDED_PAGE_SIZE*2);
// Make the get request.
$page = $adGroupCriterionService->query($pageQuery);
// Collect results.
if (isset($page->entries)) {
foreach ($page->entries as $adGroupCriterion) {
// printf("Keyword with text '%s', match type '%s', and ID '%s' was found.\n",
// $adGroupCriterion->criterion->text,
// $adGroupCriterion->criterion->matchType,
// $adGroupCriterion->criterion->id);
if ($callback) { // don't save the collection or we will run out of memory
$callback($adGroupCriterion);
} else {
$adGroupCriterions[] = $adGroupCriterion;
}
}
}
// Advance the paging offset.
$offset += AdWordsConstants::RECOMMENDED_PAGE_SIZE*2;
} while ($page->totalNumEntries > $offset);
}
}
return $adGroupCriterions;
}
$googleIds = array(); // store the found Google ids to set the rest to removed. $callback = function($adGroupCriterion) use ($adGroupLookup, &$googleIds) { ...
$googleIds[] = $adGroupCriterion->criterion->id; }; $gaw = new GoogleAdWords(); $result = $gaw->getKeywords($callback); # Google is not returning deleted keywords in PROD! Not even when selecting Status = REMOVED! Must set all remaining keywords to REMOVED $deleteGoogleIds = AdGroupKeyword::find()->select('google_id')->column(); $deleteGoogleIds = array_diff($deleteGoogleIds, $googleIds); // all that's left are the keywords that Google did not return - delete them! echo "Setting ".count($deleteGoogleIds)." keywords to status DELETED.\n"; $deleteGoogleIds = array_chunk($deleteGoogleIds, 100); // chunk it into 100 items so the DB doesn't barf foreach ($deleteGoogleIds as $batch) { Yii::$app->db->createCommand() ->update('ad_group_keyword', ['status' => Constants::DELETED], ['google_id' => $batch]) ->execute(); }