Skip to content

Commit

Permalink
Merge pull request #2252 from woocommerce/add/shipping-notifications
Browse files Browse the repository at this point in the history
Add Shipping notifications
  • Loading branch information
puntope authored Feb 14, 2024
2 parents 28790ee + a98ca65 commit 44753b0
Show file tree
Hide file tree
Showing 10 changed files with 348 additions and 55 deletions.
5 changes: 3 additions & 2 deletions src/ConnectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -637,7 +637,7 @@ protected function render_admin_page() {
<td>
<p>
<label>
Product/Coupon/Shipping ID <input name="item_id" type="text" value="<?php echo ! empty( $_GET['item_id'] ) ? intval( $_GET['item_id'] ) : ''; ?>" />
Product/Coupon ID <input name="item_id" type="text" value="<?php echo ! empty( $_GET['item_id'] ) ? intval( $_GET['item_id'] ) : ''; ?>" />
</label>
<br />
<br />
Expand All @@ -650,6 +650,7 @@ protected function render_admin_page() {
<option value="coupon.create" <?php echo $_GET['topic'] === 'coupon.create' ? "selected" : ""?>>coupon.create</option>
<option value="coupon.delete" <?php echo $_GET['topic'] === 'coupon.delete' ? "selected" : ""?>>coupon.delete</option>
<option value="coupon.update" <?php echo $_GET['topic'] === 'coupon.update' ? "selected" : ""?>>coupon.update</option>
<option value="shipping.update" <?php echo $_GET['topic'] === 'shipping.update' ? "selected" : ""?>>shipping.update</option>
</select>
</label>
<button class="button">Send Notification</button>
Expand Down Expand Up @@ -744,7 +745,7 @@ protected function handle_actions() {
$topic = $_GET['topic'];

$service = new NotificationsService();
if ( $service->notify( $item, $topic ) ) {
if ( $service->notify( $topic, $item ) ) {
$this->response .= "\n Notification success. Item: " . $item . " - Topic: " . $topic;
} else {
$this->response .= "\n Notification failed. Item: " . $item . " - Topic: " . $topic;
Expand Down
33 changes: 16 additions & 17 deletions src/Google/NotificationsService.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ class NotificationsService implements Service {
public const TOPIC_COUPON_CREATED = 'coupon.create';
public const TOPIC_COUPON_DELETED = 'coupon.delete';
public const TOPIC_COUPON_UPDATED = 'coupon.update';
public const TOPIC_SHIPPING_SAVED = 'action.woocommerce_after_shipping_zone_object_save';
public const TOPIC_SHIPPING_DELETED = 'action.woocommerce_delete_shipping_zone';
public const TOPIC_SHIPPING_UPDATED = 'shipping.update';

/**
* The url to send the notification
Expand All @@ -48,11 +47,11 @@ public function __construct() {
* Calls the Notification endpoint in WPCOM.
* https://public-api.wordpress.com/wpcom/v2/sites/{site}/partners/google/notifications
*
* @param int $item_id
* @param string $topic
* @param string $topic The topic to use in the notification.
* @param int|null $item_id The item ID to notify. It can be null for topics that doesn't need Item ID
* @return bool True is the notification is successful. False otherwise.
*/
public function notify( int $item_id, string $topic ): bool {
public function notify( string $topic, $item_id = null ): bool {
/**
* Allow users to disable the notification request.
*
Expand All @@ -66,12 +65,6 @@ public function notify( int $item_id, string $topic ): bool {
return false;
}

do_action(
'woocommerce_gla_debug_message',
sprintf( 'Notification - Item ID: %d - Topic: %s', $item_id, $topic ),
__METHOD__
);

$remote_args = [
'method' => 'POST',
'timeout' => 30,
Expand All @@ -88,24 +81,30 @@ public function notify( int $item_id, string $topic ): bool {

if ( is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) >= 400 ) {
$error = is_wp_error( $response ) ? $response->get_error_message() : wp_remote_retrieve_body( $response );
$this->notification_error( $item_id, $topic, $error );
$this->notification_error( $topic, $error, $item_id );
return false;
}

do_action(
'woocommerce_gla_debug_message',
sprintf( 'Notification - Item ID: %s - Topic: %s', $item_id, $topic ),
__METHOD__
);

return true;
}

/**
* Logs an error.
*
* @param int $item_id
* @param string $topic
* @param string $error
* @param string $topic
* @param string $error
* @param int|null $item_id
*/
private function notification_error( int $item_id, string $topic, string $error ): void {
private function notification_error( string $topic, string $error, $item_id = null ): void {
do_action(
'woocommerce_gla_error',
sprintf( 'Error sending notification for Item ID %d with topic %s. %s', $item_id, $topic, $error ),
sprintf( 'Error sending notification for Item ID %s with topic %s. %s', $item_id, $topic, $error ),
__METHOD__
);
}
Expand Down
9 changes: 8 additions & 1 deletion src/Internal/DependencyManagement/JobServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
use Automattic\WooCommerce\GoogleListingsAndAds\Jobs\JobInterface;
use Automattic\WooCommerce\GoogleListingsAndAds\Jobs\JobRepository;
use Automattic\WooCommerce\GoogleListingsAndAds\Jobs\Notifications\ProductNotificationJob;
use Automattic\WooCommerce\GoogleListingsAndAds\Jobs\Notifications\ShippingNotificationJob;
use Automattic\WooCommerce\GoogleListingsAndAds\Jobs\ProductSyncerJobInterface;
use Automattic\WooCommerce\GoogleListingsAndAds\Jobs\ProductSyncStats;
use Automattic\WooCommerce\GoogleListingsAndAds\Jobs\ResubmitExpiringProducts;
Expand Down Expand Up @@ -145,9 +146,15 @@ public function register(): void {
$this->share_with_tags( StartProductSync::class, JobRepository::class );
$this->share_with_tags( PluginUpdate::class, JobRepository::class );

// Share shipping notifications job
$this->share_action_scheduler_job(
ShippingNotificationJob::class,
NotificationsService::class
);

// Share shipping settings syncer job and hooks.
$this->share_action_scheduler_job( UpdateShippingSettings::class, MerchantCenterService::class, GoogleSettings::class );
$this->share_with_tags( Shipping\SyncerHooks::class, MerchantCenterService::class, GoogleSettings::class, JobRepository::class );
$this->share_with_tags( Shipping\SyncerHooks::class, MerchantCenterService::class, GoogleSettings::class, JobRepository::class, NotificationsService::class );

// Share plugin update jobs
$this->share_product_syncer_job( CleanupProductTargetCountriesJob::class );
Expand Down
33 changes: 21 additions & 12 deletions src/Jobs/Notifications/ProductNotificationJob.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ protected function process_items( array $args ): void {
$item = $args[0];
$topic = $args[1];

if ( $this->can_process( $item, $topic ) && $this->notifications_service->notify( $item, $topic ) ) {
if ( $this->can_process( $item, $topic ) && $this->notifications_service->notify( $topic, $item ) ) {
$this->set_status( $item, $this->get_after_notification_status( $topic ) );
}
}
Expand All @@ -86,17 +86,7 @@ protected function process_items( array $args ): void {
* @param array $args
*/
public function schedule( array $args = [] ): void {
/**
* Allow users to disable the notification job schedule.
*
* @since x.x.x
*
* @param bool $value The current filter value. By default, it is the result of `$this->can_schedule` function.
* @param array $args The arguments for the schedule function with the item id and the topic.
*/
$can_schedule = apply_filters( 'woocommerce_gla_product_notification_job_can_schedule', $this->can_schedule( [ $args ] ), $args );

if ( $can_schedule ) {
if ( $this->can_schedule( $args ) ) {
$this->action_scheduler->schedule_immediate(
$this->get_process_item_hook(),
[ $args ]
Expand Down Expand Up @@ -150,4 +140,23 @@ protected function can_process( int $product_id, string $topic ): bool {
return $this->product_helper->should_trigger_update_notification( $product );
}
}

/**
* Can the job be scheduled.
*
* @param array|null $args
*
* @return bool Returns true if the job can be scheduled.
*/
public function can_schedule( $args = [] ): bool {
/**
* Allow users to disable the notification job schedule.
*
* @since x.x.x
*
* @param bool $value The current filter value. By default, it is the result of `$this->can_schedule` function.
* @param array $args The arguments for the schedule function with the item id and the topic.
*/
return apply_filters( 'woocommerce_gla_product_notification_job_can_schedule', $this->notifications_service->is_enabled() && parent::can_schedule( $args ), $args );
}
}
101 changes: 101 additions & 0 deletions src/Jobs/Notifications/ShippingNotificationJob.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<?php
declare(strict_types=1);

namespace Automattic\WooCommerce\GoogleListingsAndAds\Jobs\Notifications;

use Automattic\WooCommerce\GoogleListingsAndAds\ActionScheduler\ActionSchedulerInterface;
use Automattic\WooCommerce\GoogleListingsAndAds\Google\NotificationsService;
use Automattic\WooCommerce\GoogleListingsAndAds\Jobs\AbstractActionSchedulerJob;
use Automattic\WooCommerce\GoogleListingsAndAds\Jobs\ActionSchedulerJobMonitor;
use Automattic\WooCommerce\GoogleListingsAndAds\Jobs\JobInterface;

defined( 'ABSPATH' ) || exit;

/**
* Class ShippingNotificationJob
* Class for the Shipping Notifications
*
* @since x.x.x
* @package Automattic\WooCommerce\GoogleListingsAndAds\Jobs\Notifications
*/
class ShippingNotificationJob extends AbstractActionSchedulerJob implements JobInterface {

/**
* @var NotificationsService $notifications_service
*/
protected $notifications_service;

/**
* @var string $topic
*/
protected $topic;

/**
* Notifications Jobs constructor.
*
* @param ActionSchedulerInterface $action_scheduler
* @param ActionSchedulerJobMonitor $monitor
* @param NotificationsService $notifications_service
*/
public function __construct(
ActionSchedulerInterface $action_scheduler,
ActionSchedulerJobMonitor $monitor,
NotificationsService $notifications_service
) {
$this->notifications_service = $notifications_service;
$this->topic = NotificationsService::TOPIC_SHIPPING_UPDATED;
parent::__construct( $action_scheduler, $monitor );
}

/**
* Get the job name
*
* @return string
*/
public function get_name(): string {
return 'notifications/shipping';
}


/**
* Logic when processing the items
*
* @param array $args Arguments with the item id and the topic
*/
protected function process_items( array $args ): void {
$this->notifications_service->notify( $this->topic );
}

/**
* Schedule the Product Notification Job
*
* @param array $args
*/
public function schedule( array $args = [] ): void {
if ( $this->can_schedule( $args ) ) {
$this->action_scheduler->schedule_immediate(
$this->get_process_item_hook(),
[ $args ]
);
}
}

/**
* Can the job be scheduled.
*
* @param array|null $args
*
* @return bool Returns true if the job can be scheduled.
*/
public function can_schedule( $args = [] ): bool {
/**
* Allow users to disable the notification job schedule.
*
* @since x.x.x
*
* @param bool $value The current filter value. By default, it is the result of `$this->can_schedule` function.
* @param array $args The arguments for the schedule function with the item id and the topic.
*/
return apply_filters( 'woocommerce_gla_shipping_notification_job_can_schedule', $this->notifications_service->is_enabled() && parent::can_schedule( $args ), $args );
}
}
31 changes: 26 additions & 5 deletions src/Shipping/SyncerHooks.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
namespace Automattic\WooCommerce\GoogleListingsAndAds\Shipping;

use Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Settings as GoogleSettings;
use Automattic\WooCommerce\GoogleListingsAndAds\Google\NotificationsService;
use Automattic\WooCommerce\GoogleListingsAndAds\Infrastructure\Registerable;
use Automattic\WooCommerce\GoogleListingsAndAds\Infrastructure\Service;
use Automattic\WooCommerce\GoogleListingsAndAds\Jobs\JobRepository;
use Automattic\WooCommerce\GoogleListingsAndAds\Jobs\Notifications\ShippingNotificationJob;
use Automattic\WooCommerce\GoogleListingsAndAds\Jobs\UpdateShippingSettings;
use Automattic\WooCommerce\GoogleListingsAndAds\MerchantCenter\MerchantCenterService;

Expand Down Expand Up @@ -45,17 +47,30 @@ class SyncerHooks implements Service, Registerable {
*/
protected $update_shipping_job;

/**
* @var NotificationsService $notifications_service
*/
protected $notifications_service;

/**
* @var ShippingNotificationJob $shipping_notification_job
*/
protected $shipping_notification_job;

/**
* SyncerHooks constructor.
*
* @param MerchantCenterService $merchant_center
* @param GoogleSettings $google_settings
* @param JobRepository $job_repository
* @param NotificationsService $notifications_service
*/
public function __construct( MerchantCenterService $merchant_center, GoogleSettings $google_settings, JobRepository $job_repository ) {
$this->google_settings = $google_settings;
$this->merchant_center = $merchant_center;
$this->update_shipping_job = $job_repository->get( UpdateShippingSettings::class );
public function __construct( MerchantCenterService $merchant_center, GoogleSettings $google_settings, JobRepository $job_repository, NotificationsService $notifications_service ) {
$this->google_settings = $google_settings;
$this->merchant_center = $merchant_center;
$this->update_shipping_job = $job_repository->get( UpdateShippingSettings::class );
$this->shipping_notification_job = $job_repository->get( ShippingNotificationJob::class );
$this->notifications_service = $notifications_service;
}

/**
Expand Down Expand Up @@ -128,7 +143,13 @@ protected function handle_update_shipping_settings() {
if ( $this->already_scheduled ) {
return;
}
$this->update_shipping_job->schedule();

if ( $this->notifications_service->is_enabled() ) {
$this->shipping_notification_job->schedule();
} else {
$this->update_shipping_job->schedule();
}

$this->already_scheduled = true;
}
}
6 changes: 3 additions & 3 deletions tests/Unit/Google/NotificationsServiceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public function test_notify() {
];

$this->service->expects( $this->once() )->method( 'do_request' )->with( $args )->willReturn( [ 'code' => 200 ] );
$this->assertTrue( $this->service->notify( $item_id, $topic ) );
$this->assertTrue( $this->service->notify( $topic, $item_id ) );
}


Expand All @@ -88,7 +88,7 @@ public function test_notify_wp_error() {
$this->service = $this->get_mock();

$this->service->expects( $this->once() )->method( 'do_request' )->willReturn( new \WP_Error( 'error', 'error message' ) );
$this->assertFalse( $this->service->notify( 1, 'topic' ) );
$this->assertFalse( $this->service->notify( 'topic', 1 ) );
$this->assertEquals( did_action( 'woocommerce_gla_error' ), 1 );
}

Expand All @@ -106,7 +106,7 @@ public function test_notify_response_error() {
],
]
);
$this->assertFalse( $this->service->notify( 1, 'topic' ) );
$this->assertFalse( $this->service->notify( 'topic', 1 ) );
$this->assertEquals( did_action( 'woocommerce_gla_error' ), 1 );
}

Expand Down
Loading

0 comments on commit 44753b0

Please sign in to comment.