From d128d8a276e3fee2348361ca7a37eb073764e090 Mon Sep 17 00:00:00 2001 From: Jorge M Date: Wed, 17 Jul 2024 19:51:51 +0200 Subject: [PATCH] Add pagination header for the campaign endpoint --- src/API/Google/AdsCampaign.php | 18 ++++++++++++-- src/API/Google/Query/AdsQuery.php | 2 ++ .../Controllers/Ads/CampaignController.php | 24 ++++++++++++++++--- 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/src/API/Google/AdsCampaign.php b/src/API/Google/AdsCampaign.php index 60ce9bb183..c8a825d499 100644 --- a/src/API/Google/AdsCampaign.php +++ b/src/API/Google/AdsCampaign.php @@ -102,11 +102,12 @@ public function __construct( GoogleAdsClient $client, AdsCampaignBudget $budget, * @param bool $exclude_removed Exclude removed campaigns (default true). * @param bool $fetch_criterion Combine the campaign data with criterion data (default true). * @param array $args Arguments for the Ads Campaign Query for example: per_page for limiting the number of results. + * @param bool $return_pagination_params Whether to return pagination params (default false). * * @return array * @throws ExceptionWithResponseData When an ApiException is caught. */ - public function get_campaigns( bool $exclude_removed = true, bool $fetch_criterion = true, $args = [] ): array { + public function get_campaigns( bool $exclude_removed = true, bool $fetch_criterion = true, $args = [], $return_pagination_params = false ): array { try { $query = ( new AdsCampaignQuery( $args ) )->set_client( $this->client, $this->options->get_ads_id() ); @@ -118,7 +119,10 @@ public function get_campaigns( bool $exclude_removed = true, bool $fetch_criteri $campaign_results = $query->get_results(); $converted_campaigns = []; - foreach ( $campaign_results->getPage()->getIterator() as $row ) { + /** @var Page $page */ + $page = $campaign_results->getPage(); + + foreach ( $page->getIterator() as $row ) { ++$campaign_count; $campaign = $this->convert_campaign( $row ); $converted_campaigns[ $campaign['id'] ] = $campaign; @@ -137,6 +141,16 @@ public function get_campaigns( bool $exclude_removed = true, bool $fetch_criteri $converted_campaigns = $this->combine_campaigns_and_campaign_criterion_results( $converted_campaigns ); } + if ( $return_pagination_params ) { + // Total results across all pages. + $total_results = $page->getResponseObject()->getTotalResultsCount(); + $next_page_token = $page->getNextPageToken(); + return [ + 'campaigns' => array_values( $converted_campaigns ), + 'total_results' => $total_results, + 'next_page_token' => $next_page_token, + ]; + } return array_values( $converted_campaigns ); } catch ( ApiException $e ) { do_action( 'woocommerce_gla_ads_client_exception', $e, __METHOD__ ); diff --git a/src/API/Google/Query/AdsQuery.php b/src/API/Google/Query/AdsQuery.php index 9bddd403cc..8caaf0758d 100644 --- a/src/API/Google/Query/AdsQuery.php +++ b/src/API/Google/Query/AdsQuery.php @@ -91,6 +91,8 @@ protected function query_results() { } $request = new SearchGoogleAdsRequest(); + // Allow us to get the total number of results for pagination. + $request->setReturnTotalResultsCount( true ); if ( ! empty( $this->search_args['pageSize'] ) ) { $request->setPageSize( $this->search_args['pageSize'] ); diff --git a/src/API/Site/Controllers/Ads/CampaignController.php b/src/API/Site/Controllers/Ads/CampaignController.php index 6de77e1979..2d51784b31 100644 --- a/src/API/Site/Controllers/Ads/CampaignController.php +++ b/src/API/Site/Controllers/Ads/CampaignController.php @@ -99,15 +99,33 @@ public function register_routes(): void { protected function get_campaigns_callback(): callable { return function ( Request $request ) { try { - $exclude_removed = $request->get_param( 'exclude_removed' ); + $exclude_removed = $request->get_param( 'exclude_removed' ); + $return_pagination_params = true; + $campaign_data = $this->ads_campaign->get_campaigns( $exclude_removed, true, $request->get_params(), $return_pagination_params ); - return array_map( + $campaigns = array_map( function ( $campaign ) use ( $request ) { $data = $this->prepare_item_for_response( $campaign, $request ); return $this->prepare_response_for_collection( $data ); }, - $this->ads_campaign->get_campaigns( $exclude_removed, true, $request->get_params() ) + $campaign_data['campaigns'] ); + + $response = rest_ensure_response( $campaigns ); + + $total_campaigns = (int) $campaign_data['total_results']; + $response->header( 'X-WP-Total', $total_campaigns ); + // If per_page is not set, then set it to total number of campaigns. + $per_page = $request->get_param( 'per_page' ) ?: $total_campaigns; + $max_pages = $per_page > 0 ? ceil( $total_campaigns / $per_page ) : 1; + $response->header( 'X-WP-TotalPages', (int) $max_pages ); + + if ( ! empty( $campaign_data['next_page_token'] ) ) { + $response->header( 'X-GLA-NextPageToken', $campaign_data['next_page_token'] ); + } + + return $response; + } catch ( Exception $e ) { return $this->response_from_exception( $e ); }