Skip to content

Google Pull work integration branch. #2981

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

Open
wants to merge 47 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
6a17228
Block Shipping, Products and Coupons when Sync Push is disabled
puntope Mar 4, 2025
ee41e72
Block Sync Push when Dattype Push Sync is disabled
puntope Mar 16, 2025
148886e
Tweak connection test
puntope Mar 16, 2025
22ffc80
Tweak tests
puntope Mar 16, 2025
fe31caf
Tweak tests
puntope Mar 16, 2025
26cee5e
Tweak tests
puntope Mar 16, 2025
ac7f186
Tweak tests
puntope Mar 16, 2025
8b5a675
Tweak tests
puntope Mar 16, 2025
cece311
Tweak tests
puntope Mar 16, 2025
acb3615
Fix extra "the" in the string.
budzanowski Apr 28, 2025
3830928
Fix extra "the" in the string.
budzanowski Apr 28, 2025
0864a31
Refactor dockblock for MerchantCenterService::is_enabled_for_datatype.
budzanowski Apr 28, 2025
36064d7
Block push syncs based on settings.
budzanowski Apr 28, 2025
5174066
Fix tests: mock is_enabled_for_datatype method
budzanowski May 29, 2025
861bd7d
Fix whitespace issue.
budzanowski May 29, 2025
09e5832
Add the G4W settings to WC REST API
tomalec Mar 23, 2025
9547221
Move `gla_*` settings from `…/general` to `…/google-for-woocommerce`
tomalec Mar 29, 2025
98ce3a0
Add all inputs from the onboarding to `settings/g-4-w`
tomalec Mar 30, 2025
0a21a91
Reduce complexity of `prepare_data` for requests other than `shipping…
tomalec Mar 30, 2025
225d0a5
Move `settings/` back behind `gla_syncable` check,
tomalec Mar 30, 2025
abfc007
Fix whitespace for PHPCS
tomalec Mar 30, 2025
1f9057e
Tune the empty settings hack.
tomalec Mar 30, 2025
893d288
Cast shipping rates and times to object,
tomalec Mar 30, 2025
a13d6d3
Add .md with expected schema
tomalec Mar 30, 2025
d40f654
Tune the empty settings hack.
tomalec Mar 30, 2025
65ca501
Fix PHPCS
tomalec Mar 30, 2025
804718d
Fix tests
tomalec Mar 30, 2025
9dbe385
Add code docs on `gla_syncable`
tomalec Mar 30, 2025
f976bbb
Fix merge artifact form `settings/google-for-woocommerce` test
tomalec Mar 30, 2025
a78d9a4
Apply copilot suggestions
tomalec Mar 30, 2025
585b61a
Fix currency code in shipping rates response
tomalec Mar 31, 2025
198437f
Improve code docs
tomalec Mar 31, 2025
909c4b0
Make `prefix_name` protected again
tomalec Mar 31, 2025
2090dab
Remove `gla_jetpack_connected` YAGNI,
tomalec Mar 31, 2025
621bae0
Update src/DB/Query/ShippingRateQuery.php
budzanowski Apr 17, 2025
89b81b4
Remove `is_wpcom_api_authorized` method as authorization is granted b…
budzanowski Jun 23, 2025
eb61fd9
Fix PHP coding standards - remove extra blank lines before closing br…
budzanowski Jun 23, 2025
2a55c75
Fix PHPDoc comment for get_mock method parameters
budzanowski Jun 23, 2025
42533bc
Fix WPCOM API partner token validation for client credentials
budzanowski Jun 25, 2025
469b673
Fix test for client credentials auto-approval logic
budzanowski Jun 25, 2025
f6f6e83
Fix whitespace.
budzanowski Jun 25, 2025
0af693c
One more whitespace.
budzanowski Jun 25, 2025
8355a47
Remove one more trainling whitespace
budzanowski Jun 25, 2025
4dbe299
Remove opt-in/opt-out UI controls for product data sync
budzanowski Jun 26, 2025
e5982a4
Fix linting: Remove extra blank line
budzanowski Jun 26, 2025
2062bc5
Implement INTEGRA-49: Add blog_id to all notification messages
budzanowski Jun 27, 2025
1608578
Merge pull request #2989 from woocommerce/feature/integra-49-add-blog…
budzanowski Jun 27, 2025
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
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
* External dependencies
*/
import { sprintf, __ } from '@wordpress/i18n';
import { useState } from '@wordpress/element';
import { getSetting } from '@woocommerce/settings'; // eslint-disable-line import/no-unresolved
// The above is an unpublished package, delivered with WC, we use Dependency Extraction Webpack Plugin to import it.
// See https://github.com/woocommerce/woocommerce-admin/issues/7781
Expand All @@ -11,94 +10,24 @@ import { getSetting } from '@woocommerce/settings'; // eslint-disable-line impor
* Internal dependencies
*/
import AccountCard, { APPEARANCE } from '~/components/account-card';
import AppButton from '~/components/app-button';
import ConnectedIconLabel from '~/components/connected-icon-label';
import Section from '~/components/section';
import { GOOGLE_WPCOM_APP_CONNECTED_STATUS } from '~/constants';
import { API_NAMESPACE } from '~/data/constants';
import useDispatchCoreNotices from '~/hooks/useDispatchCoreNotices';
import useApiFetchCallback from '~/hooks/useApiFetchCallback';
import { useAppDispatch } from '~/data';
import EnableNewProductSyncButton from '~/components/enable-new-product-sync-button';
import AppNotice from '~/components/app-notice';
import DisconnectModal, {
API_DATA_FETCH_FEATURE,
} from '~/pages/settings/disconnect-modal';
import { getSettingsUrl } from '~/utils/urls';
import { recordGlaEvent } from '~/utils/tracks';

/**
* @typedef {import('~/data/types.js').GoogleMCAccount} GoogleMCAccount
*/

/**
* Clicking on the button to disable the new product sync (API Pull).
*
* @event gla_disable_product_sync_click
*/

/**
* Renders a Google Merchant Center account card UI with connected account information.
*
* @param {Object} props React props.
* @param {GoogleMCAccount} props.googleMCAccount A data payload object of Google Merchant Center account.
*
* @fires gla_disable_product_sync_click
*/
const MerchantCenterAccountInfoCard = ( { googleMCAccount } ) => {
const { createNotice, removeNotice } = useDispatchCoreNotices();
const { invalidateResolution } = useAppDispatch();

const [
fetchDisableNotifications,
{ loading: loadingDisableNotifications },
] = useApiFetchCallback( {
path: `${ API_NAMESPACE }/rest-api/authorize`,
method: 'DELETE',
} );

/**
* Temporary code for disabling the API PULL Beta Feature from the GMC Card
*/
const [ openedModal, setOpenedModal ] = useState( null );
const dismissModal = () => setOpenedModal( null );
const openDisableDataFetchModal = () =>
setOpenedModal( API_DATA_FETCH_FEATURE );

const domain = new URL( getSetting( 'homeUrl' ) ).host;

const disableNotifications = async () => {
recordGlaEvent( 'gla_disable_product_sync_click' );

const { notice } = await createNotice(
'info',
__(
'Disabling the new Product Sync feature, please wait…',
'google-listings-and-ads'
)
);

try {
await fetchDisableNotifications();
invalidateResolution( 'getGoogleMCAccount', [] );
} catch ( error ) {
createNotice(
'error',
__(
'Unable to disable new product sync. Please try again later.',
'google-listings-and-ads'
)
);
}

removeNotice( notice.id );
};

// Show the button if the status is "approved".
const showDisconnectNotificationsButton =
googleMCAccount.wpcom_rest_api_status ===
GOOGLE_WPCOM_APP_CONNECTED_STATUS.APPROVED;

// Show the error if the status is set but is not "approved".
const showErrorNotificationsNotice =
googleMCAccount.wpcom_rest_api_status &&
Expand Down Expand Up @@ -126,15 +55,6 @@ const MerchantCenterAccountInfoCard = ( { googleMCAccount } ) => {
)
}
>
{ showDisconnectNotificationsButton && (
<AppNotice status="success" isDismissible={ false }>
{ __(
'Google has been granted access to fetch your product data.',
'google-listings-and-ads'
) }
</AppNotice>
) }

{ showErrorNotificationsNotice && (
<AppNotice status="warning" isDismissible={ false }>
{ __(
Expand All @@ -143,32 +63,6 @@ const MerchantCenterAccountInfoCard = ( { googleMCAccount } ) => {
) }
</AppNotice>
) }

{ openedModal && (
<DisconnectModal
onRequestClose={ dismissModal }
onDisconnected={ () => {
window.location.href = getSettingsUrl();
} }
disconnectTarget={ openedModal }
disconnectAction={ disableNotifications }
/>
) }

{ showDisconnectNotificationsButton && (
<Section.Card.Footer>
<AppButton
isDestructive
isLink
disabled={ loadingDisableNotifications }
text={ __(
'Disable product data fetch',
'google-listings-and-ads'
) }
onClick={ openDisableDataFetchModal }
/>
</Section.Card.Footer>
) }
</AccountCard>
);
};
Expand Down
20 changes: 1 addition & 19 deletions js/src/pages/settings/disconnect-modal/confirm-modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import AppModal from '~/components/app-modal';
import AppButton from '~/components/app-button';
import WarningIcon from '~/components/warning-icon';
import { useAppDispatch } from '~/data';
import { ALL_ACCOUNTS, ADS_ACCOUNT, API_DATA_FETCH_FEATURE } from './constants';
import { ALL_ACCOUNTS, ADS_ACCOUNT } from './constants';

const textDict = {
[ ALL_ACCOUNTS ]: {
Expand Down Expand Up @@ -66,24 +66,6 @@ const textDict = {
),
],
},
[ API_DATA_FETCH_FEATURE ]: {
title: __( 'Disable data fetching', 'google-listings-and-ads' ),
confirmButton: __( 'Disable data fetching', 'google-listings-and-ads' ),
confirmation: __(
'Yes, I want to disable the data fetching feature.',
'google-listings-and-ads'
),
contents: [
__(
'I understand that I am disabling the data fetching feature from this WooCommerce extension.',
'google-listings-and-ads'
),
__(
'Any ongoing campaigns and configuration will continue to run. They will be pushed to Google as in the previous versions of this extension.',
'google-listings-and-ads'
),
],
},
};

export default function ConfirmModal( {
Expand Down
1 change: 0 additions & 1 deletion js/src/pages/settings/disconnect-modal/constants.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
export const ALL_ACCOUNTS = 'all-accounts';
export const ADS_ACCOUNT = 'ads-account';
export const API_DATA_FETCH_FEATURE = 'api-data-fetch-feature';
2 changes: 0 additions & 2 deletions js/src/pages/settings/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import LinkedAccounts from './linked-accounts';
import ReconnectWPComAccount from './reconnect-wpcom-account';
import ReconnectGoogleAccount from './reconnect-google-account';
import EditStoreAddress from './edit-store-address';
import EnableNewProductSyncNotice from '~/components/enable-new-product-sync-notice';
import MainTabNav from '~/components/main-tab-nav';
import RebrandingTour from '~/components/tours/rebranding-tour';
import './index.scss';
Expand Down Expand Up @@ -62,7 +61,6 @@ const Settings = () => {

return (
<div className={ pageClassName }>
<EnableNewProductSyncNotice />
<MainTabNav />
<RebrandingTour />
<ContactInformationPreview />
Expand Down
6 changes: 5 additions & 1 deletion src/API/Google/Settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@

namespace Automattic\WooCommerce\GoogleListingsAndAds\API\Google;

use Automattic\WooCommerce\GoogleListingsAndAds\API\WP\NotificationsService;
use Automattic\WooCommerce\GoogleListingsAndAds\DB\Query\ShippingRateQuery;
use Automattic\WooCommerce\GoogleListingsAndAds\DB\Query\ShippingTimeQuery;
use Automattic\WooCommerce\GoogleListingsAndAds\Internal\ContainerAwareTrait;
use Automattic\WooCommerce\GoogleListingsAndAds\Internal\Interfaces\ContainerAwareInterface;
use Automattic\WooCommerce\GoogleListingsAndAds\MerchantCenter\MerchantCenterService;
use Automattic\WooCommerce\GoogleListingsAndAds\MerchantCenter\TargetAudience;
use Automattic\WooCommerce\GoogleListingsAndAds\Options\OptionsInterface;
use Automattic\WooCommerce\GoogleListingsAndAds\Proxies\WC;
Expand Down Expand Up @@ -65,7 +67,9 @@
* Sync the shipping settings with Google.
*/
public function sync_shipping() {
if ( ! $this->should_sync_shipping() ) {
/** @var MerchantCenterService $merchant_center */
$merchant_center = $this->container->get( MerchantCenterService::class );
if ( ! $this->should_sync_shipping() || ! $merchant_center->is_enabled_for_datatype( NotificationsService::DATATYPE_SHIPPING ) ) {

Check warning on line 72 in src/API/Google/Settings.php

View check run for this annotation

Codecov / codecov/patch

src/API/Google/Settings.php#L71-L72

Added lines #L71 - L72 were not covered by tests
return;
}

Expand Down
24 changes: 18 additions & 6 deletions src/API/WP/NotificationsService.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,13 @@ class NotificationsService implements Service, OptionsAwareInterface {
*/
private $notification_url;

/**
* The WordPress.com blog ID
*
* @var int $blog_id
*/
private $blog_id;

/**
* The Merchant center service
*
Expand All @@ -97,10 +104,10 @@ class NotificationsService implements Service, OptionsAwareInterface {
* @param AccountService $account_service
*/
public function __construct( MerchantCenterService $merchant_center, AccountService $account_service ) {
$blog_id = Jetpack_Options::get_option( 'id' );
$this->blog_id = Jetpack_Options::get_option( 'id' );
$this->merchant_center = $merchant_center;
$this->account_service = $account_service;
$this->notification_url = "https://public-api.wordpress.com/wpcom/v2/sites/{$blog_id}/partners/google/notifications";
$this->notification_url = "https://public-api.wordpress.com/wpcom/v2/sites/{$this->blog_id}/partners/google/notifications";
}

/**
Expand Down Expand Up @@ -130,7 +137,6 @@ public function notify( string $topic, $item_id = null, $data = [] ): bool {
'message' => 'Notification was not sent because the Notification Service is not ready or the topic is not valid.',
'data_type' => $this->get_datatype_from_topic( $topic ),
'topic_is_valid' => $this->yes_or_no( $is_valid_topic ),
'wpcom_authorized' => $this->yes_or_no( $this->options->is_wpcom_api_authorized() ),
'wpcom_healthy' => $this->yes_or_no( $this->account_service->is_wpcom_api_status_healthy() ),
'mc_sync_ready' => $this->yes_or_no( $this->merchant_center->is_ready_for_syncing() ),
'notification_service_status' => $this->enabled_or_disabled( $this->is_enabled() ),
Expand All @@ -149,7 +155,13 @@ public function notify( string $topic, $item_id = null, $data = [] ): bool {
'x-woocommerce-topic' => $topic,
'Content-Type' => 'application/json',
],
'body' => array_merge( $data, [ 'item_id' => $item_id ] ),
'body' => array_merge(
$data,
[
'item_id' => $item_id,
'blog_id' => $this->blog_id,
]
),
'url' => $this->get_notification_url(),
];

Expand Down Expand Up @@ -206,14 +218,14 @@ public function get_notification_url(): string {

/**
* If the Notifications are ready
* This happens when the WPCOM API is Authorized and the feature is enabled.
* This happens when the feature is enabled and Merchant Center is ready for syncing.
*
* @param string|null $data_type The data type to check.
* @param bool $with_health_check If true. Performs a remote request to WPCOM API to get the status.
* * @return bool
*/
public function is_ready( string $data_type = null, bool $with_health_check = true ): bool {
$is_ready = $this->options->is_wpcom_api_authorized() && $this->is_enabled() && $this->merchant_center->is_ready_for_syncing() && ( $with_health_check === false || $this->account_service->is_wpcom_api_status_healthy() );
$is_ready = $this->is_enabled() && $this->merchant_center->is_ready_for_syncing() && ( $with_health_check === false || $this->account_service->is_wpcom_api_status_healthy() );
return $is_ready && ( is_null( $data_type ) || $this->is_pull_enabled_for_datatype( $data_type ) );
}

Expand Down
42 changes: 40 additions & 2 deletions src/ConnectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,9 @@
$this->response .= 'Failed to connect to Google.';
}

$notification_service = new NotificationsService( $this->container->get( MerchantCenterService::class ), $this->container->get( AccountService::class ) );
$notification_service->set_options_object( $options );

Check warning on line 140 in src/ConnectionTest.php

View check run for this annotation

Codecov / codecov/patch

src/ConnectionTest.php#L139-L140

Added lines #L139 - L140 were not covered by tests

?>
<div class="wrap">
<h2>Connection Test</h2>
Expand Down Expand Up @@ -572,7 +575,44 @@
<hr />

<h2 class="title">Product Sync</h2>
<table class="form-table" role="presentation">
<tr>
<th><label>Products MC PUSH:</label></th>
<td>
<p>

<code><?php echo $this->enabled_or_disabled( $notification_service->is_push_enabled_for_datatype( NotificationsService::DATATYPE_PRODUCT ) ); ?></code>

Check warning on line 584 in src/ConnectionTest.php

View check run for this annotation

Codecov / codecov/patch

src/ConnectionTest.php#L584

Added line #L584 was not covered by tests
</p>
</td>
</tr>
<tr>
<th><label>Coupons MC PUSH:</label></th>
<td>
<p>

<code><?php echo $this->enabled_or_disabled( $notification_service->is_push_enabled_for_datatype( NotificationsService::DATATYPE_COUPON ) ); ?></code>

Check warning on line 593 in src/ConnectionTest.php

View check run for this annotation

Codecov / codecov/patch

src/ConnectionTest.php#L593

Added line #L593 was not covered by tests
</p>
</td>
</tr>
<tr>
<th><label>Shipping MC PUSH:</label></th>
<td>
<p>

<code><?php echo $this->enabled_or_disabled( $notification_service->is_push_enabled_for_datatype( NotificationsService::DATATYPE_SHIPPING ) ); ?></code>

Check warning on line 602 in src/ConnectionTest.php

View check run for this annotation

Codecov / codecov/patch

src/ConnectionTest.php#L602

Added line #L602 was not covered by tests
</p>
</td>
</tr>
<tr>
<th><label>Settings MC PUSH:</label></th>
<td>
<p>

<code><?php echo $this->enabled_or_disabled( $notification_service->is_push_enabled_for_datatype( NotificationsService::DATATYPE_SETTINGS ) ); ?></code>

Check warning on line 611 in src/ConnectionTest.php

View check run for this annotation

Codecov / codecov/patch

src/ConnectionTest.php#L611

Added line #L611 was not covered by tests
</p>
</td>
</tr>
</table>
<form action="<?php echo esc_url( admin_url( 'admin.php' ) ); ?>" method="GET">
<table class="form-table" role="presentation">
<tr>
Expand Down Expand Up @@ -673,8 +713,6 @@
<?php
$options = $this->container->get( OptionsInterface::class );
$wp_api_status = $options->get( OptionsInterface::WPCOM_REST_API_STATUS );
$notification_service = new NotificationsService( $this->container->get( MerchantCenterService::class ), $this->container->get( AccountService::class ) );
$notification_service->set_options_object( $options );
?>
<h2 class="title">Partner API Pull Integration</h2>
<form action="<?php echo esc_url( admin_url( 'admin.php' ) ); ?>" method="GET">
Expand Down
20 changes: 18 additions & 2 deletions src/Coupon/CouponSyncer.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
declare(strict_types = 1);
namespace Automattic\WooCommerce\GoogleListingsAndAds\Coupon;

use Automattic\WooCommerce\GoogleListingsAndAds\API\WP\NotificationsService;
use Automattic\WooCommerce\GoogleListingsAndAds\Google\DeleteCouponEntry;
use Automattic\WooCommerce\GoogleListingsAndAds\Google\GooglePromotionService;
use Automattic\WooCommerce\GoogleListingsAndAds\Google\InvalidCouponEntry;
Expand Down Expand Up @@ -479,13 +480,28 @@
if ( ! $this->merchant_center->should_push() ) {
do_action(
'woocommerce_gla_error',
'Cannot push any coupons because they are being fetched automatically.',
'Cannot push any coupons because your store is not ready for syncing.',

Check warning on line 483 in src/Coupon/CouponSyncer.php

View check run for this annotation

Codecov / codecov/patch

src/Coupon/CouponSyncer.php#L483

Added line #L483 was not covered by tests
__METHOD__
);

throw new CouponSyncerException(
__(
'Pushing Coupons will not run if the automatic data fetching is enabled. Please review your configuration in Google Listing and Ads settings.',
'Pushing coupons will not run if the store is not ready for syncing.',
'google-listings-and-ads'
)
);

Check warning on line 492 in src/Coupon/CouponSyncer.php

View check run for this annotation

Codecov / codecov/patch

src/Coupon/CouponSyncer.php#L489-L492

Added lines #L489 - L492 were not covered by tests
}

if ( ! $this->merchant_center->is_enabled_for_datatype( NotificationsService::DATATYPE_COUPON ) ) {
do_action(
'woocommerce_gla_error',
'Cannot push any coupons because the syncing feature has been disabled on your store.',
__METHOD__
);

throw new CouponSyncerException(
__(
'Pushing Coupons will not run if the PUSH Sync functionality has been disabled.',
'google-listings-and-ads'
)
);
Expand Down
Loading