Skip to content

Commit

Permalink
Merge pull request #2137 from woocommerce/tweak/2130-track-campaign-c…
Browse files Browse the repository at this point in the history
…ount

Add tracking for campaign count
  • Loading branch information
mikkamp authored Oct 25, 2023
2 parents 780d233 + 853eef1 commit 4cb36d5
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 1 deletion.
16 changes: 16 additions & 0 deletions src/API/Google/AdsCampaign.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Automattic\WooCommerce\GoogleListingsAndAds\Options\OptionsAwareInterface;
use Automattic\WooCommerce\GoogleListingsAndAds\Options\OptionsAwareTrait;
use Automattic\WooCommerce\GoogleListingsAndAds\Options\OptionsInterface;
use Automattic\WooCommerce\GoogleListingsAndAds\Options\TransientsInterface;
use Automattic\WooCommerce\GoogleListingsAndAds\Proxies\WC;
use Google\Ads\GoogleAds\Util\FieldMasks;
use Google\Ads\GoogleAds\Util\V14\ResourceNames;
Expand All @@ -35,6 +36,7 @@
*
* ContainerAware used for:
* - AdsAssetGroup
* - TransientsInterface
* - WC
*
* @since 1.12.2 Refactored to support PMax and (legacy) SSC.
Expand Down Expand Up @@ -110,14 +112,25 @@ public function get_campaigns( bool $exclude_removed = true, bool $fetch_criteri
$query->where( 'campaign.status', 'REMOVED', '!=' );
}

$campaign_count = 0;
$campaign_results = $query->get_results();
$converted_campaigns = [];

foreach ( $campaign_results->iterateAllElements() as $row ) {
$campaign_count++;
$campaign = $this->convert_campaign( $row );
$converted_campaigns[ $campaign['id'] ] = $campaign;
}

if ( $exclude_removed ) {
// Cache campaign count.
$this->container->get( TransientsInterface::class )->set(
TransientsInterface::ADS_CAMPAIGN_COUNT,
$campaign_count,
HOUR_IN_SECONDS * 12
);
}

if ( $fetch_criterion ) {
$converted_campaigns = $this->combine_campaigns_and_campaign_criterion_results( $converted_campaigns );
}
Expand Down Expand Up @@ -220,6 +233,9 @@ function ( $country_code ) {

$campaign_id = $this->mutate( $operations );

// Clear cached campaign count.
$this->container->get( TransientsInterface::class )->delete( TransientsInterface::ADS_CAMPAIGN_COUNT );

return [
'id' => $campaign_id,
'status' => CampaignStatus::ENABLED,
Expand Down
37 changes: 37 additions & 0 deletions src/API/Google/MerchantMetrics.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
namespace Automattic\WooCommerce\GoogleListingsAndAds\API\Google;

use Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query\AdsCampaignReportQuery;
use Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query\AdsCampaignQuery;
use Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query\MerchantFreeListingReportQuery;
use Automattic\WooCommerce\GoogleListingsAndAds\Google\Ads\GoogleAdsClient;
use Automattic\WooCommerce\GoogleListingsAndAds\Options\OptionsAwareInterface;
Expand Down Expand Up @@ -187,6 +188,42 @@ public function get_cached_ads_metrics(): array {
return $value;
}

/**
* Return amount of active campaigns for the connected Ads account.
*
* @since x.x.x
*
* @return int
*/
public function get_campaign_count(): int {
if ( ! $this->options->get_ads_id() ) {
return 0;
}

$campaign_count = 0;
$cached_count = $this->transients->get( TransientsInterface::ADS_CAMPAIGN_COUNT );
if ( null !== $cached_count ) {
return (int) $cached_count;
}

try {
$query = ( new AdsCampaignQuery() )->set_client( $this->ads_client, $this->options->get_ads_id() );
$query->where( 'campaign.status', 'REMOVED', '!=' );

$campaign_results = $query->get_results();

// Iterate through all paged results (total results count is not set).
foreach ( $campaign_results->iterateAllElements() as $row ) {
$campaign_count++;
}
} catch ( Exception $e ) {
$campaign_count = 0;
}

$this->transients->set( TransientsInterface::ADS_CAMPAIGN_COUNT, $campaign_count, HOUR_IN_SECONDS * 12 );
return $campaign_count;
}

/**
* Get tomorrow's date to ensure we include any metrics from the current day.
*
Expand Down
3 changes: 3 additions & 0 deletions src/Ads/AccountService.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Automattic\WooCommerce\GoogleListingsAndAds\Options\OptionsAwareInterface;
use Automattic\WooCommerce\GoogleListingsAndAds\Options\OptionsAwareTrait;
use Automattic\WooCommerce\GoogleListingsAndAds\Options\OptionsInterface;
use Automattic\WooCommerce\GoogleListingsAndAds\Options\TransientsInterface;
use Automattic\WooCommerce\GoogleListingsAndAds\Vendor\Psr\Container\ContainerInterface;
use Exception;

Expand All @@ -28,6 +29,7 @@
* - AdsConversionAction
* - Merchant
* - Middleware
* - TransientsInterface
*
* @since 1.11.0
* @package Automattic\WooCommerce\GoogleListingsAndAds\Ads
Expand Down Expand Up @@ -216,6 +218,7 @@ public function disconnect() {
$this->options->delete( OptionsInterface::ADS_ID );
$this->options->delete( OptionsInterface::ADS_SETUP_COMPLETED_AT );
$this->options->delete( OptionsInterface::CAMPAIGN_CONVERT_STATUS );
$this->container->get( TransientsInterface::class )->delete( TransientsInterface::ADS_CAMPAIGN_COUNT );
}

/**
Expand Down
2 changes: 2 additions & 0 deletions src/Options/TransientsInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
*/
interface TransientsInterface {

public const ADS_CAMPAIGN_COUNT = 'ads_campaign_count';
public const ADS_METRICS = 'ads_metrics';
public const FREE_LISTING_METRICS = 'free_listing_metrics';
public const MC_ACCOUNT_REVIEW = 'mc_account_review';
Expand All @@ -18,6 +19,7 @@ interface TransientsInterface {
public const URL_MATCHES = 'url_matches';

public const VALID_OPTIONS = [
self::ADS_CAMPAIGN_COUNT => true,
self::ADS_METRICS => true,
self::FREE_LISTING_METRICS => true,
self::MC_ACCOUNT_REVIEW => true,
Expand Down
10 changes: 9 additions & 1 deletion src/Tracking/TrackerSnapshot.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
namespace Automattic\WooCommerce\GoogleListingsAndAds\Tracking;

use Automattic\WooCommerce\GoogleListingsAndAds\Ads\AdsService;
use Automattic\WooCommerce\GoogleListingsAndAds\API\Google\MerchantMetrics;
use Automattic\WooCommerce\GoogleListingsAndAds\Infrastructure\Conditional;
use Automattic\WooCommerce\GoogleListingsAndAds\Infrastructure\Registerable;
use Automattic\WooCommerce\GoogleListingsAndAds\Infrastructure\Service;
Expand All @@ -20,7 +21,10 @@
* Include Google Listings and Ads data in the WC Tracker snapshot.
*
* ContainerAware used to access:
* - MerchantStatuses
* - AdsService
* - MerchantCenterService
* - MerchantMetrics
* - TargetAudience
*
* @package Automattic\WooCommerce\GoogleListingsAndAds\Tracking
*/
Expand Down Expand Up @@ -83,6 +87,8 @@ protected function get_settings(): array {
$ads_service = $this->container->get( AdsService::class );
/** @var MerchantCenterService $mc_service */
$mc_service = $this->container->get( MerchantCenterService::class );
/** @var MerchantMetrics $merchant_metrics */
$merchant_metrics = $this->container->get( MerchantMetrics::class );

return [
'version' => $this->get_version(),
Expand All @@ -98,6 +104,8 @@ protected function get_settings(): array {
'has_account_issue' => $mc_service->is_connected() && $mc_service->has_account_issues() ? 'yes' : 'no',
'has_at_least_one_synced_product' => $mc_service->is_connected() && $mc_service->has_at_least_one_synced_product() ? 'yes' : 'no',
'ads_setup_started' => $ads_service->is_setup_started() ? 'yes' : 'no',
'ads_customer_id' => $this->options->get_ads_id(),
'ads_campaign_count' => $merchant_metrics->get_campaign_count(),
];
}

Expand Down
6 changes: 6 additions & 0 deletions tests/Unit/API/Google/AdsCampaignTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use Automattic\WooCommerce\GoogleListingsAndAds\Google\GoogleHelper;
use Automattic\WooCommerce\GoogleListingsAndAds\Exception\ExceptionWithResponseData;
use Automattic\WooCommerce\GoogleListingsAndAds\Options\OptionsInterface;
use Automattic\WooCommerce\GoogleListingsAndAds\Options\TransientsInterface;
use Automattic\WooCommerce\GoogleListingsAndAds\Proxies\WC;
use Automattic\WooCommerce\GoogleListingsAndAds\Tests\Framework\UnitTest;
use Automattic\WooCommerce\GoogleListingsAndAds\Tests\Tools\HelperTrait\GoogleAdsClientTrait;
Expand Down Expand Up @@ -42,6 +43,9 @@ class AdsCampaignTest extends UnitTest {
/** @var MockObject|OptionsInterface $options */
protected $options;

/** @var MockObject|TransientsInterface $transients */
protected $transients;

/** @var AdsCampaign $campaign */
protected $campaign;

Expand Down Expand Up @@ -69,12 +73,14 @@ public function setUp(): void {
$this->budget = $this->createMock( AdsCampaignBudget::class );
$this->criterion = new AdsCampaignCriterion();
$this->options = $this->createMock( OptionsInterface::class );
$this->transients = $this->createMock( TransientsInterface::class );

$this->wc = $this->createMock( WC::class );
$this->google_helper = new GoogleHelper( $this->wc );

$this->container = new Container();
$this->container->share( AdsAssetGroup::class, $this->asset_group );
$this->container->share( TransientsInterface::class, $this->transients );
$this->container->share( WC::class, $this->wc );

$this->campaign = new AdsCampaign( $this->client, $this->budget, $this->criterion, $this->google_helper );
Expand Down
12 changes: 12 additions & 0 deletions tests/Unit/Ads/AccountServiceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use Automattic\WooCommerce\GoogleListingsAndAds\Exception\ExceptionWithResponseData;
use Automattic\WooCommerce\GoogleListingsAndAds\Options\AdsAccountState;
use Automattic\WooCommerce\GoogleListingsAndAds\Options\OptionsInterface;
use Automattic\WooCommerce\GoogleListingsAndAds\Options\TransientsInterface;
use Automattic\WooCommerce\GoogleListingsAndAds\Tests\Framework\UnitTest;
use Automattic\WooCommerce\GoogleListingsAndAds\Vendor\League\Container\Container;
use Exception;
Expand Down Expand Up @@ -41,6 +42,9 @@ class AccountServiceTest extends UnitTest {
/** @var MockObject|AdsAccountState $state */
protected $state;

/** @var MockObject|TransientsInterface $transients */
protected $transients;

/** @var AccountService $account */
protected $account;

Expand Down Expand Up @@ -104,13 +108,15 @@ public function setUp(): void {
$this->middleware = $this->createMock( Middleware::class );
$this->state = $this->createMock( AdsAccountState::class );
$this->options = $this->createMock( OptionsInterface::class );
$this->transients = $this->createMock( TransientsInterface::class );

$this->container = new Container();
$this->container->share( Ads::class, $this->ads );
$this->container->share( AdsConversionAction::class, $this->conversion_action );
$this->container->share( Merchant::class, $this->merchant );
$this->container->share( Middleware::class, $this->middleware );
$this->container->share( AdsAccountState::class, $this->state );
$this->container->share( TransientsInterface::class, $this->transients );

$this->account = new AccountService( $this->container );
$this->account->set_options_object( $this->options );
Expand Down Expand Up @@ -467,6 +473,12 @@ public function test_disconnect() {
[ OptionsInterface::CAMPAIGN_CONVERT_STATUS ]
);

$this->transients->expects( $this->exactly( 1 ) )
->method( 'delete' )
->withConsecutive(
[ TransientsInterface::ADS_CAMPAIGN_COUNT ],
);

$this->account->disconnect();
}

Expand Down

0 comments on commit 4cb36d5

Please sign in to comment.