Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create product statuses jobs for each page token #2255

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/API/Google/MerchantReport.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@
* @param ShoppingContent $service
* @param ProductHelper $product_helper
*/
public function __construct( ShoppingContent $service, ProductHelper $product_helper ) {
$this->service = $service;
$this->product_helper = $product_helper;

Check warning on line 56 in src/API/Google/MerchantReport.php

View check run for this annotation

Codecov / codecov/patch

src/API/Google/MerchantReport.php#L54-L56

Added lines #L54 - L56 were not covered by tests
}

/**
Expand All @@ -64,19 +64,19 @@
*
* @throws Exception If the product view report data can't be retrieved.
*/
public function get_product_view_report( $next_page_token = null ): array {
$batch_size = apply_filters( 'woocommerce_gla_product_view_report_page_size', 1000 );

Check warning on line 68 in src/API/Google/MerchantReport.php

View check run for this annotation

Codecov / codecov/patch

src/API/Google/MerchantReport.php#L67-L68

Added lines #L67 - L68 were not covered by tests

try {
$product_view_data = [
'statuses' => [],
'next_page' => null,
];

Check warning on line 74 in src/API/Google/MerchantReport.php

View check run for this annotation

Codecov / codecov/patch

src/API/Google/MerchantReport.php#L71-L74

Added lines #L71 - L74 were not covered by tests

$query = new MerchantProductViewReportQuery(
[
'next_page' => $next_page_token,
'per_page' => $batch_size,

Check warning on line 79 in src/API/Google/MerchantReport.php

View check run for this annotation

Codecov / codecov/patch

src/API/Google/MerchantReport.php#L79

Added line #L79 was not covered by tests
]
);

Expand All @@ -84,33 +84,33 @@
->set_client( $this->service, $this->options->get_merchant_id() )
->get_results();

foreach ( $response->getResults() as $row ) {

Check warning on line 87 in src/API/Google/MerchantReport.php

View check run for this annotation

Codecov / codecov/patch

src/API/Google/MerchantReport.php#L87

Added line #L87 was not covered by tests

/** @var ProductView $product_view */
$product_view = $row->getProductView();

Check warning on line 90 in src/API/Google/MerchantReport.php

View check run for this annotation

Codecov / codecov/patch

src/API/Google/MerchantReport.php#L90

Added line #L90 was not covered by tests

$wc_product_id = $this->product_helper->get_wc_product_id( $product_view->getId() );
$mc_product_status = $this->convert_aggregated_status_to_mc_status( $product_view->getAggregatedDestinationStatus() );

Check warning on line 93 in src/API/Google/MerchantReport.php

View check run for this annotation

Codecov / codecov/patch

src/API/Google/MerchantReport.php#L92-L93

Added lines #L92 - L93 were not covered by tests

// Skip if the product id does not exist
if ( ! $wc_product_id ) {
continue;

Check warning on line 97 in src/API/Google/MerchantReport.php

View check run for this annotation

Codecov / codecov/patch

src/API/Google/MerchantReport.php#L96-L97

Added lines #L96 - L97 were not covered by tests
}

$product_view_data['statuses'][] = [
'product_id' => $wc_product_id,
'status' => $mc_product_status,
'expiration_date' => $this->convert_shopping_content_date( $product_view->getExpirationDate() ),
];

Check warning on line 104 in src/API/Google/MerchantReport.php

View check run for this annotation

Codecov / codecov/patch

src/API/Google/MerchantReport.php#L100-L104

Added lines #L100 - L104 were not covered by tests

}

$product_view_data['next_page'] = $response->getNextPageToken();
$product_view_data['next_page_token'] = $response->getNextPageToken();

Check warning on line 108 in src/API/Google/MerchantReport.php

View check run for this annotation

Codecov / codecov/patch

src/API/Google/MerchantReport.php#L108

Added line #L108 was not covered by tests

return $product_view_data;
} catch ( GoogleException $e ) {
do_action( 'woocommerce_gla_mc_client_exception', $e, __METHOD__ );
throw new Exception( __( 'Unable to retrieve Product View Report.', 'google-listings-and-ads' ) . $e->getMessage(), $e->getCode() );

Check warning on line 113 in src/API/Google/MerchantReport.php

View check run for this annotation

Codecov / codecov/patch

src/API/Google/MerchantReport.php#L110-L113

Added lines #L110 - L113 were not covered by tests
}
}

Expand All @@ -121,18 +121,18 @@
*
* @return string The MC status.
*/
protected function convert_aggregated_status_to_mc_status( string $status ): string {

Check warning on line 124 in src/API/Google/MerchantReport.php

View check run for this annotation

Codecov / codecov/patch

src/API/Google/MerchantReport.php#L124

Added line #L124 was not covered by tests
switch ( $status ) {
case 'ELIGIBLE':
return MCStatus::APPROVED;
case 'ELIGIBLE_LIMITED':
return MCStatus::PARTIALLY_APPROVED;
case 'NOT_ELIGIBLE_OR_DISAPPROVED':
return MCStatus::DISAPPROVED;
case 'PENDING':
return MCStatus::PENDING;

Check warning on line 133 in src/API/Google/MerchantReport.php

View check run for this annotation

Codecov / codecov/patch

src/API/Google/MerchantReport.php#L126-L133

Added lines #L126 - L133 were not covered by tests
default:
return MCStatus::NOT_SYNCED;

Check warning on line 135 in src/API/Google/MerchantReport.php

View check run for this annotation

Codecov / codecov/patch

src/API/Google/MerchantReport.php#L135

Added line #L135 was not covered by tests
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,11 @@
*
* @return Response
*/
protected function get_product_status_stats( Request $request, bool $force_refresh = false ): Response {

Check warning on line 109 in src/API/Site/Controllers/MerchantCenter/ProductStatisticsController.php

View check run for this annotation

Codecov / codecov/patch

src/API/Site/Controllers/MerchantCenter/ProductStatisticsController.php#L109

Added line #L109 was not covered by tests
try {
$response = $this->merchant_statuses->get_product_statistics( $force_refresh );

Check warning on line 111 in src/API/Site/Controllers/MerchantCenter/ProductStatisticsController.php

View check run for this annotation

Codecov / codecov/patch

src/API/Site/Controllers/MerchantCenter/ProductStatisticsController.php#L111

Added line #L111 was not covered by tests

$response['scheduled_sync'] = $this->sync_stats->get_count();

Check warning on line 113 in src/API/Site/Controllers/MerchantCenter/ProductStatisticsController.php

View check run for this annotation

Codecov / codecov/patch

src/API/Site/Controllers/MerchantCenter/ProductStatisticsController.php#L113

Added line #L113 was not covered by tests

return $this->prepare_item_for_response( $response, $request );
} catch ( Exception $e ) {
Expand All @@ -125,13 +125,13 @@
*/
protected function get_schema_properties(): array {
return [
'timestamp' => [
'type' => 'number',
'description' => __( 'Timestamp reflecting when the product status statistics were last generated.', 'google-listings-and-ads' ),
'context' => [ 'view' ],
'readonly' => true,
],
'statistics' => [

Check warning on line 134 in src/API/Site/Controllers/MerchantCenter/ProductStatisticsController.php

View check run for this annotation

Codecov / codecov/patch

src/API/Site/Controllers/MerchantCenter/ProductStatisticsController.php#L128-L134

Added lines #L128 - L134 were not covered by tests
'type' => 'object',
'description' => __( 'Merchant Center product status statistics.', 'google-listings-and-ads' ),
'context' => [ 'view' ],
Expand Down Expand Up @@ -164,12 +164,18 @@
],
],
],
'scheduled_sync' => [
'type' => 'number',
'description' => __( 'Amount of scheduled jobs which will sync products to Google.', 'google-listings-and-ads' ),
'context' => [ 'view' ],
'readonly' => true,
],
'loading' => [
'type' => 'boolean',
'description' => __( 'Whether the product statistics are loading.', 'google-listings-and-ads' ),
'context' => [ 'view' ],
'readonly' => true,
],

Check warning on line 178 in src/API/Site/Controllers/MerchantCenter/ProductStatisticsController.php

View check run for this annotation

Codecov / codecov/patch

src/API/Site/Controllers/MerchantCenter/ProductStatisticsController.php#L167-L178

Added lines #L167 - L178 were not covered by tests
];
}

Expand Down
31 changes: 19 additions & 12 deletions src/Jobs/UpdateMerchantProductStatuses.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,18 +82,24 @@
* @throws JobException If the shipping settings cannot be synced.
*/
public function process_items( array $items ) {
$next_page_token = null;
$next_page_token = $items['next_page_token'] ?? null;

do {
$results = $this->merchant_report->get_product_view_report( $next_page_token );

$this->merchant_statuses->process_product_statuses( $results['statuses'] );
// Clear the cache if we're starting from the beginning.
if ( ! $next_page_token ) {
$this->merchant_statuses->clear_cache();
$this->merchant_statuses->delete_product_statuses_count_intermediate_data();
}

$next_page_token = $results['next_page'];
$results = $this->merchant_report->get_product_view_report( $next_page_token );
$next_page_token = $results['next_page_token'];

} while ( $next_page_token );
$this->merchant_statuses->update_product_stats( $results['statuses'] );

$this->merchant_statuses->update_product_stats();
if ( $next_page_token ) {
$this->schedule( [ [ 'next_page_token' => $next_page_token ] ] );
} else {
$this->merchant_statuses->handle_complete_mc_statuses_fetching();
}
}

/**
Expand All @@ -102,17 +108,18 @@
* @param array $args - arguments.
*/
public function schedule( array $args = [] ) {
if ( $this->can_schedule() ) {
$this->action_scheduler->schedule_immediate( $this->get_process_item_hook() );
if ( $this->can_schedule( $args ) ) {
$this->action_scheduler->schedule_immediate( $this->get_process_item_hook(), $args );
}
}

/**
* The job is considered to be scheduled if the "process_item" action is currently pending or in-progress.
* The job is considered to be scheduled if the "process_item" action is currently pending or in-progress regardless of the arguments.
*
* @return bool
*/
public function is_scheduled(): bool {

Check warning on line 121 in src/Jobs/UpdateMerchantProductStatuses.php

View check run for this annotation

Codecov / codecov/patch

src/Jobs/UpdateMerchantProductStatuses.php#L121

Added line #L121 was not covered by tests
return $this->is_running();
// We set 'args' to null so it matches any arguments. This is because it's possible to have multiple instances of the job running with different page tokens
return $this->is_running( null );

Check warning on line 123 in src/Jobs/UpdateMerchantProductStatuses.php

View check run for this annotation

Codecov / codecov/patch

src/Jobs/UpdateMerchantProductStatuses.php#L123

Added line #L123 was not covered by tests
}
}
167 changes: 114 additions & 53 deletions src/MerchantCenter/MerchantStatuses.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
use Automattic\WooCommerce\GoogleListingsAndAds\Value\MCStatus;
use Automattic\WooCommerce\GoogleListingsAndAds\Vendor\Google\Service\ShoppingContent\ProductStatus as GoogleProductStatus;
use Automattic\WooCommerce\GoogleListingsAndAds\Jobs\UpdateMerchantProductStatuses;
use Automattic\WooCommerce\GoogleListingsAndAds\Options\OptionsAwareInterface;
use Automattic\WooCommerce\GoogleListingsAndAds\Options\OptionsAwareTrait;
use Automattic\WooCommerce\GoogleListingsAndAds\Options\OptionsInterface;
use DateTime;
use Exception;

Expand All @@ -37,11 +40,13 @@
* - ProductHelper
* - ProductRepository
* - TransientsInterface
* - UpdateMerchantProductStatuses
*
* @package Automattic\WooCommerce\GoogleListingsAndAds\MerchantCenter
*/
class MerchantStatuses implements Service, ContainerAwareInterface {
class MerchantStatuses implements Service, ContainerAwareInterface, OptionsAwareInterface {

use OptionsAwareTrait;
use ContainerAwareTrait;
use PluginHelper;

Expand Down Expand Up @@ -105,9 +110,11 @@
* @param bool $force_refresh Force refresh of all product status data.
*
* @return array The product status statistics.
* @throws Exception If the Merchant Center can't be polled for the statuses.
* @throws Exception If no Merchant Center account is connected, or account status is not retrievable.
*/
public function get_product_statistics( bool $force_refresh = false ): array {
$this->check_mc_is_connected();

$this->mc_statuses = $this->container->get( TransientsInterface::class )->get( Transients::MC_STATUSES );
$job = $this->container->get( UpdateMerchantProductStatuses::class );

Expand All @@ -118,10 +125,10 @@
}

if ( $job->is_scheduled() || null === $this->mc_statuses ) {
// TODO: Add a notice to the client to inform that the statuses are being updated, or maybe we can pass the is_scheduled to the client.
return [
'timestamp' => $this->cache_created_time->getTimestamp(),
'statistics' => [],
'loading' => true,
];
}

Expand Down Expand Up @@ -173,6 +180,36 @@
$this->container->get( TransientsInterface::class )->delete( TransientsInterface::MC_STATUSES );
}

/**
* Delete the intermediate product status count data.
*
* @since x.x.x
*/
public function delete_product_statuses_count_intermediate_data(): void {
$this->options->delete( OptionsInterface::PRODUCT_STATUSES_COUNT_INTERMEDIATE_DATA );

Check warning on line 189 in src/MerchantCenter/MerchantStatuses.php

View check run for this annotation

Codecov / codecov/patch

src/MerchantCenter/MerchantStatuses.php#L188-L189

Added lines #L188 - L189 were not covered by tests
}

/**
* Check if the Merchant Center account is connected and throw an exception if it's not.
*
* @since x.x.x
*
* @throws Exception If the Merchant Center account is not connected.
*/
protected function check_mc_is_connected() {
$mc_service = $this->container->get( MerchantCenterService::class );

if ( ! $mc_service->is_connected() ) {

// Return a 401 to redirect to reconnect flow if the Google account is not connected.
if ( ! $mc_service->is_google_connected() ) {
throw new Exception( __( 'Google account is not connected.', 'google-listings-and-ads' ), 401 );
}

throw new Exception( __( 'Merchant Center account is not set up.', 'google-listings-and-ads' ) );
}
}

/**
* Update stale status-related data - account issues, product issues, products status stats.
*
Expand All @@ -184,20 +221,11 @@
// Only refresh if the current data has expired.
$this->mc_statuses = $this->container->get( TransientsInterface::class )->get( Transients::MC_STATUSES );
if ( ! $force_refresh && null !== $this->mc_statuses ) {
return;

Check warning on line 224 in src/MerchantCenter/MerchantStatuses.php

View check run for this annotation

Codecov / codecov/patch

src/MerchantCenter/MerchantStatuses.php#L224

Added line #L224 was not covered by tests
}

// Save a request if accounts are not connected.
$mc_service = $this->container->get( MerchantCenterService::class );
if ( ! $mc_service->is_connected() ) {

// Return a 401 to redirect to reconnect flow if the Google account is not connected.
if ( ! $mc_service->is_google_connected() ) {
throw new Exception( __( 'Google account is not connected.', 'google-listings-and-ads' ), 401 );
}

throw new Exception( __( 'Merchant Center account is not set up.', 'google-listings-and-ads' ) );
}
$this->check_mc_is_connected();

// Update account-level issues.
$this->refresh_account_issues();
Expand Down Expand Up @@ -588,63 +616,75 @@
* @param array[] $statuses statuses.
* @see MerchantReport::get_product_view_report
*/
public function process_product_statuses( $statuses ): void {
public function process_product_statuses( array $statuses ): void {
$this->product_statuses = [
'products' => [],
'parents' => [],
];

Check warning on line 623 in src/MerchantCenter/MerchantStatuses.php

View check run for this annotation

Codecov / codecov/patch

src/MerchantCenter/MerchantStatuses.php#L619-L623

Added lines #L619 - L623 were not covered by tests

/** @var ProductHelper $product_helper */
$product_helper = $this->container->get( ProductHelper::class );
$visibility_meta_key = $this->prefix_meta_key( ProductMetaHandler::KEY_VISIBILITY );

Check warning on line 627 in src/MerchantCenter/MerchantStatuses.php

View check run for this annotation

Codecov / codecov/patch

src/MerchantCenter/MerchantStatuses.php#L626-L627

Added lines #L626 - L627 were not covered by tests

foreach ( $statuses as $product_status ) {

Check warning on line 629 in src/MerchantCenter/MerchantStatuses.php

View check run for this annotation

Codecov / codecov/patch

src/MerchantCenter/MerchantStatuses.php#L629

Added line #L629 was not covered by tests

$wc_product_id = $product_status['product_id'];
$mc_product_status = $product_status['status'];

Check warning on line 632 in src/MerchantCenter/MerchantStatuses.php

View check run for this annotation

Codecov / codecov/patch

src/MerchantCenter/MerchantStatuses.php#L631-L632

Added lines #L631 - L632 were not covered by tests

// Skip if the product does not exist or if the product previously found/validated.
if ( ! $wc_product_id || ! empty( $this->product_data_lookup[ $wc_product_id ] ) ) {
continue;

Check warning on line 636 in src/MerchantCenter/MerchantStatuses.php

View check run for this annotation

Codecov / codecov/patch

src/MerchantCenter/MerchantStatuses.php#L635-L636

Added lines #L635 - L636 were not covered by tests
}

if ( $this->product_is_expiring( $product_status['expiration_date'] ) ) {
$mc_product_status = MCStatus::EXPIRING;

Check warning on line 640 in src/MerchantCenter/MerchantStatuses.php

View check run for this annotation

Codecov / codecov/patch

src/MerchantCenter/MerchantStatuses.php#L639-L640

Added lines #L639 - L640 were not covered by tests
}

$wc_product = $product_helper->get_wc_product_by_wp_post( $wc_product_id );
if ( ! $wc_product || 'product' !== substr( $wc_product->post_type, 0, 7 ) ) {

Check warning on line 644 in src/MerchantCenter/MerchantStatuses.php

View check run for this annotation

Codecov / codecov/patch

src/MerchantCenter/MerchantStatuses.php#L643-L644

Added lines #L643 - L644 were not covered by tests
// Should never reach here since the products IDS are retrieved from postmeta.
do_action(
'woocommerce_gla_debug_message',
sprintf( 'Merchant Center product %s not found in this WooCommerce store.', $wc_product_id ),
__METHOD__,
);

Check warning on line 650 in src/MerchantCenter/MerchantStatuses.php

View check run for this annotation

Codecov / codecov/patch

src/MerchantCenter/MerchantStatuses.php#L646-L650

Added lines #L646 - L650 were not covered by tests
continue;
}

$this->product_data_lookup[ $wc_product_id ] = [
'name' => get_the_title( $wc_product ),
'visibility' => get_post_meta( $wc_product_id, $visibility_meta_key ),
'parent_id' => $wc_product->post_parent,
];

Check warning on line 658 in src/MerchantCenter/MerchantStatuses.php

View check run for this annotation

Codecov / codecov/patch

src/MerchantCenter/MerchantStatuses.php#L654-L658

Added lines #L654 - L658 were not covered by tests

// Products is used later for global product status statistics.
$this->product_statuses['products'][ $wc_product_id ][ $mc_product_status ] = 1 + ( $this->product_statuses['products'][ $wc_product_id ][ $mc_product_status ] ?? 0 );

Check warning on line 661 in src/MerchantCenter/MerchantStatuses.php

View check run for this annotation

Codecov / codecov/patch

src/MerchantCenter/MerchantStatuses.php#L661

Added line #L661 was not covered by tests

// Aggregate parent statuses for mc_status postmeta.
$wc_parent_id = $this->product_data_lookup[ $wc_product_id ]['parent_id'];

Check warning on line 664 in src/MerchantCenter/MerchantStatuses.php

View check run for this annotation

Codecov / codecov/patch

src/MerchantCenter/MerchantStatuses.php#L664

Added line #L664 was not covered by tests
if ( ! $wc_parent_id ) {
continue;
}
$this->product_statuses['parents'][ $wc_parent_id ][ $mc_product_status ] = 1 + ( $this->product_statuses['parents'][ $wc_parent_id ][ $mc_product_status ] ?? 0 );

Check warning on line 668 in src/MerchantCenter/MerchantStatuses.php

View check run for this annotation

Codecov / codecov/patch

src/MerchantCenter/MerchantStatuses.php#L668

Added line #L668 was not covered by tests

}
}

/**
* Update the product status statistics.
* Update the product status statistics for a list of products statuses.
*
* @since x.x.x
*
* @param array[] $statuses statuses. See statuses format in MerchantReport::get_product_view_report.
*/
public function update_product_stats() {
public function update_product_stats( array $statuses ): void {
$this->mc_statuses = [];

Check warning on line 681 in src/MerchantCenter/MerchantStatuses.php

View check run for this annotation

Codecov / codecov/patch

src/MerchantCenter/MerchantStatuses.php#L680-L681

Added lines #L680 - L681 were not covered by tests

$this->process_product_statuses( $statuses );

Check warning on line 683 in src/MerchantCenter/MerchantStatuses.php

View check run for this annotation

Codecov / codecov/patch

src/MerchantCenter/MerchantStatuses.php#L683

Added line #L683 was not covered by tests

// Update each product's mc_status and then update the global statistics.
$this->update_products_meta_with_mc_status();
$this->update_mc_status_statistics();
$this->update_intermediate_product_statistics();

Check warning on line 687 in src/MerchantCenter/MerchantStatuses.php

View check run for this annotation

Codecov / codecov/patch

src/MerchantCenter/MerchantStatuses.php#L686-L687

Added lines #L686 - L687 were not covered by tests
}

/**
Expand All @@ -654,17 +694,17 @@
*
* @return bool Whether the product is expiring.
*/
protected function product_is_expiring( DateTime $expiration_date ): bool {
if ( ! $expiration_date ) {
return false;

Check warning on line 699 in src/MerchantCenter/MerchantStatuses.php

View check run for this annotation

Codecov / codecov/patch

src/MerchantCenter/MerchantStatuses.php#L697-L699

Added lines #L697 - L699 were not covered by tests
}

// Products are considered expiring if they will expire within 3 days.
return time() + 3 * DAY_IN_SECONDS > $expiration_date->getTimestamp();

Check warning on line 703 in src/MerchantCenter/MerchantStatuses.php

View check run for this annotation

Codecov / codecov/patch

src/MerchantCenter/MerchantStatuses.php#L703

Added line #L703 was not covered by tests
}

/**
* Calculate the synced product status statistics. It will group
* Sum and update the intermediate product status statistics. It will group
* the variations for the same parent.
*
* For the case that one variation is approved and the other disapproved:
Expand All @@ -675,7 +715,7 @@
*
* @return array Product status statistics.
*/
protected function calculate_synced_product_statistics(): array {
protected function update_intermediate_product_statistics(): array {

Check warning on line 718 in src/MerchantCenter/MerchantStatuses.php

View check run for this annotation

Codecov / codecov/patch

src/MerchantCenter/MerchantStatuses.php#L718

Added line #L718 was not covered by tests
$product_statistics = [
MCStatus::APPROVED => 0,
MCStatus::PARTIALLY_APPROVED => 0,
Expand All @@ -685,6 +725,12 @@
MCStatus::NOT_SYNCED => 0,
];

// If the option is set, use it to sum the total quantity.
$product_statistics_intermediate_data = $this->options->get( OptionsInterface::PRODUCT_STATUSES_COUNT_INTERMEDIATE_DATA );
if ( $product_statistics_intermediate_data ) {
$product_statistics = $product_statistics_intermediate_data;

Check warning on line 731 in src/MerchantCenter/MerchantStatuses.php

View check run for this annotation

Codecov / codecov/patch

src/MerchantCenter/MerchantStatuses.php#L729-L731

Added lines #L729 - L731 were not covered by tests
}

$product_statistics_priority = [
MCStatus::APPROVED => 6,
MCStatus::PARTIALLY_APPROVED => 5,
Expand Down Expand Up @@ -716,36 +762,69 @@
$product_statistics[ $parent_status ] += 1;
}

$this->options->update( OptionsInterface::PRODUCT_STATUSES_COUNT_INTERMEDIATE_DATA, $product_statistics );

Check warning on line 765 in src/MerchantCenter/MerchantStatuses.php

View check run for this annotation

Codecov / codecov/patch

src/MerchantCenter/MerchantStatuses.php#L765

Added line #L765 was not covered by tests

return $product_statistics;
}

/**
* Calculate the product status statistics and update the transient.
* Calculate the total count of products in the MC using the statistics.
*
* @since x.x.x
*
* @param array $statistics
*
* @return int
*/
protected function update_mc_status_statistics() {
$product_statistics = $this->calculate_synced_product_statistics();
protected function calculate_total_synced_product_statistics( array $statistics ): int {
if ( ! count( $statistics ) ) {
return 0;

Check warning on line 781 in src/MerchantCenter/MerchantStatuses.php

View check run for this annotation

Codecov / codecov/patch

src/MerchantCenter/MerchantStatuses.php#L779-L781

Added lines #L779 - L781 were not covered by tests
}

/** @var ProductRepository $product_repository */
$product_repository = $this->container->get( ProductRepository::class );
$product_statistics[ MCStatus::NOT_SYNCED ] = count( $product_repository->find_mc_not_synced_product_ids() );
$synced_status_values = array_values( array_diff( $statistics, [ $statistics[ MCStatus::NOT_SYNCED ] ] ) );
return array_sum( $synced_status_values );

Check warning on line 785 in src/MerchantCenter/MerchantStatuses.php

View check run for this annotation

Codecov / codecov/patch

src/MerchantCenter/MerchantStatuses.php#L784-L785

Added lines #L784 - L785 were not covered by tests
}

$this->mc_statuses = [
'timestamp' => $this->cache_created_time->getTimestamp(),
'statistics' => $product_statistics,
];

// Update the cached values
$this->container->get( TransientsInterface::class )->set(
Transients::MC_STATUSES,
$this->mc_statuses,
$this->get_status_lifetime()
);
/**
* Handle the completion of the Merchant Center statuses fetching.
*
* @since x.x.x
*/
public function handle_complete_mc_statuses_fetching() {
$intermediate_data = $this->options->get( OptionsInterface::PRODUCT_STATUSES_COUNT_INTERMEDIATE_DATA );

Check warning on line 795 in src/MerchantCenter/MerchantStatuses.php

View check run for this annotation

Codecov / codecov/patch

src/MerchantCenter/MerchantStatuses.php#L794-L795

Added lines #L794 - L795 were not covered by tests

if ( $intermediate_data ) {

Check warning on line 797 in src/MerchantCenter/MerchantStatuses.php

View check run for this annotation

Codecov / codecov/patch

src/MerchantCenter/MerchantStatuses.php#L797

Added line #L797 was not covered by tests

$total_synced_products = $this->calculate_total_synced_product_statistics( $intermediate_data );

Check warning on line 799 in src/MerchantCenter/MerchantStatuses.php

View check run for this annotation

Codecov / codecov/patch

src/MerchantCenter/MerchantStatuses.php#L799

Added line #L799 was not covered by tests

/** @var ProductRepository $product_repository */
$product_repository = $this->container->get( ProductRepository::class );
$intermediate_data[ MCStatus::NOT_SYNCED ] = count(
$product_repository->find_all_product_ids()
) - $total_synced_products;

Check warning on line 805 in src/MerchantCenter/MerchantStatuses.php

View check run for this annotation

Codecov / codecov/patch

src/MerchantCenter/MerchantStatuses.php#L802-L805

Added lines #L802 - L805 were not covered by tests

$mc_statuses = [
'timestamp' => $this->cache_created_time->getTimestamp(),
'statistics' => $intermediate_data,
'loading' => false,
];

Check warning on line 811 in src/MerchantCenter/MerchantStatuses.php

View check run for this annotation

Codecov / codecov/patch

src/MerchantCenter/MerchantStatuses.php#L807-L811

Added lines #L807 - L811 were not covered by tests

$this->container->get( TransientsInterface::class )->set(
Transients::MC_STATUSES,
$mc_statuses,
$this->get_status_lifetime()
);

Check warning on line 817 in src/MerchantCenter/MerchantStatuses.php

View check run for this annotation

Codecov / codecov/patch

src/MerchantCenter/MerchantStatuses.php#L813-L817

Added lines #L813 - L817 were not covered by tests

$this->delete_product_statuses_count_intermediate_data();

Check warning on line 819 in src/MerchantCenter/MerchantStatuses.php

View check run for this annotation

Codecov / codecov/patch

src/MerchantCenter/MerchantStatuses.php#L819

Added line #L819 was not covered by tests
}
}


/**
* Update the Merchant Center status for each product.
*/
protected function update_products_meta_with_mc_status() {

Check warning on line 827 in src/MerchantCenter/MerchantStatuses.php

View check run for this annotation

Codecov / codecov/patch

src/MerchantCenter/MerchantStatuses.php#L827

Added line #L827 was not covered by tests
// Generate a product_id=>mc_status array.
$new_product_statuses = [];
foreach ( $this->product_statuses as $types ) {
Expand All @@ -767,16 +846,11 @@
}
ksort( $new_product_statuses );

/** @var ProductRepository $product_repository */
$product_repository = $this->container->get( ProductRepository::class );

/** @var ProductMetaQueryHelper $product_meta_query_helper */
$product_meta_query_helper = $this->container->get( ProductMetaQueryHelper::class );

// Get all MC statuses.
$current_product_statuses = $product_meta_query_helper->get_all_values( ProductMetaHandler::KEY_MC_STATUS );
// Get all product IDs.
$all_product_ids = array_flip( $product_repository->find_ids() );

// Format: product_id=>status.
$to_insert = [];
Expand All @@ -791,21 +865,8 @@
// MC status not same as WC, update.
$to_update[ $new_status ][] = intval( $product_id );
}
// Unset all found statuses from WC products array.
unset( $all_product_ids[ $product_id ] );
}

// Set products NOT FOUND in MC to NOT_SYNCED.
foreach ( array_keys( $all_product_ids ) as $product_id ) {
if ( empty( $current_product_statuses[ $product_id ] ) ) {
$to_insert[ $product_id ] = MCStatus::NOT_SYNCED;
} elseif ( $current_product_statuses[ $product_id ] !== MCStatus::NOT_SYNCED ) {
$to_update[ MCStatus::NOT_SYNCED ][] = $product_id;
}
}

unset( $all_product_ids, $current_product_statuses, $new_product_statuses );

// Insert and update changed MC Status postmeta.
$product_meta_query_helper->batch_insert_values( ProductMetaHandler::KEY_MC_STATUS, $to_insert );
foreach ( $to_update as $status => $product_ids ) {
Expand Down
2 changes: 2 additions & 0 deletions src/Options/OptionsInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ interface OptionsInterface {
public const SITE_VERIFICATION = 'site_verification';
public const SYNCABLE_PRODUCTS_COUNT = 'syncable_products_count';
public const SYNCABLE_PRODUCTS_COUNT_INTERMEDIATE_DATA = 'syncable_products_count_intermediate_data';
public const PRODUCT_STATUSES_COUNT_INTERMEDIATE_DATA = 'product_statuses_count_intermediate_data';
public const TARGET_AUDIENCE = 'target_audience';
public const TOURS = 'tours';
public const UPDATE_ALL_PRODUCTS_LAST_SYNC = 'update_all_products_last_sync';
Expand Down Expand Up @@ -68,6 +69,7 @@ interface OptionsInterface {
self::SITE_VERIFICATION => true,
self::SYNCABLE_PRODUCTS_COUNT => true,
self::SYNCABLE_PRODUCTS_COUNT_INTERMEDIATE_DATA => true,
self::PRODUCT_STATUSES_COUNT_INTERMEDIATE_DATA => true,
self::TARGET_AUDIENCE => true,
self::TOURS => true,
self::UPDATE_ALL_PRODUCTS_LAST_SYNC => true,
Expand Down
Loading
Loading