PluginProbe
WooCommerce / 11.1.0-rc.2
WooCommerce v11.1.0-rc.2
11.1.0 11.1.0-rc.2 11.1.0-rc.1 11.1.0-beta.2 11.1.0-beta.1 11.0.1 11.0.0 11.0.0-rc.3 11.0.0-rc.2 11.0.0-rc.1 11.0.0-beta.2 11.0.0-beta.1 10.9.4 10.9.3 10.9.2 10.9.1 10.9.0 10.9.0-rc.1 10.9.0-beta.2 10.9.0-beta.1 10.8.1 10.8.0 10.8.0-rc.1 10.8.0-beta.2 10.8.0-beta.1 All 648 releases
woocommerce / src / Internal / StockNotifications / StockSyncController.php
StockSyncController.php
202 lines 5.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 declare( strict_types = 1 );
4
5 namespace Automattic\WooCommerce\Internal\StockNotifications;
6
7 use Automattic\WooCommerce\Internal\StockNotifications\Utilities\EligibilityService;
8 use Automattic\WooCommerce\Internal\StockNotifications\AsyncTasks\JobManager;
9 use WC_Product;
10
11 /**
12 * The controller for the stock events.
13 */
14 class StockSyncController {
15
16 /**
17 * The queue using product IDs as keys.
18 *
19 * @var array<int, bool>
20 */
21 private array $queue = array();
22
23 /**
24 * The eligibility service instance.
25 *
26 * @var EligibilityService
27 */
28 private EligibilityService $eligibility_service;
29
30 /**
31 * The job manager instance.
32 *
33 * @var JobManager
34 */
35 private JobManager $job_manager;
36
37 /**
38 * Logger instance.
39 *
40 * @var \WC_Logger_Interface
41 */
42 protected $logger;
43
44 /**
45 * Init.
46 *
47 * @internal
48 *
49 * @param EligibilityService $eligibility_service The eligibility service instance.
50 * @param JobManager $job_manager The job manager instance.
51 */
52 final public function init(
53 EligibilityService $eligibility_service,
54 JobManager $job_manager
55 ): void {
56 $this->logger = \wc_get_logger();
57 $this->eligibility_service = $eligibility_service;
58 $this->job_manager = $job_manager;
59 }
60
61 /**
62 * Constructor.
63 */
64 public function __construct() {
65 // Event handlers.
66 add_action( 'woocommerce_product_set_stock_status', array( $this, 'handle_product_stock_status_change' ), 100, 3 );
67 add_action( 'woocommerce_variation_set_stock_status', array( $this, 'handle_product_stock_status_change' ), 100, 3 );
68
69 // Process the queue on shutdown.
70 add_action( 'shutdown', array( $this, 'process_queue' ) );
71
72 // Output the admin notice.
73 add_action( 'admin_notices', array( $this, 'output_admin_notice' ) );
74 }
75
76 /**
77 * Handle product stock status changes.
78 *
79 * @param int $product_id The product ID.
80 * @param string $stock_status The new stock status.
81 * @param WC_Product|null $product The product object (optional).
82 * @return void
83 */
84 public function handle_product_stock_status_change( $product_id, $stock_status, $product = null ) {
85
86 try {
87
88 if ( ! $this->eligibility_service->is_stock_status_eligible( $stock_status ) ) {
89 return;
90 }
91
92 if ( null === $product ) {
93 $product = \wc_get_product( $product_id );
94 }
95
96 if ( ! is_a( $product, 'WC_Product' ) ) {
97 return;
98 }
99
100 if ( ! $this->eligibility_service->is_product_eligible( $product ) ) {
101 return;
102 }
103
104 if ( ! $this->eligibility_service->has_active_notifications( $product ) ) {
105 return;
106 }
107
108 // Add to queue.
109 $target_product_ids = $this->eligibility_service->get_target_product_ids( $product );
110 foreach ( $target_product_ids as $target_product_id ) {
111 $this->queue[ $target_product_id ] = true;
112 }
113
114 $this->store_admin_notice( $product->get_id() );
115
116 } catch ( \Throwable $e ) {
117 $this->logger->error(
118 sprintf( 'StockSyncController: Failed to process product %d: %s', $product_id, $e->getMessage() ),
119 array( 'source' => 'wc-customer-stock-notifications' )
120 );
121 }
122 }
123
124 /**
125 * Process the product IDs in the queue.
126 *
127 * Called on shutdown to schedule Action Scheduler jobs
128 * for each product ID in the queue.
129 *
130 * @return void
131 */
132 public function process_queue(): void {
133 if ( empty( $this->queue ) || ! is_array( $this->queue ) ) {
134 $this->queue = array();
135 return;
136 }
137
138 $product_ids = array_filter( array_keys( $this->queue ) );
139 if ( empty( $product_ids ) ) {
140 return;
141 }
142
143 foreach ( $product_ids as $product_id ) {
144 $this->job_manager->schedule_initial_job_for_product( $product_id );
145 }
146
147 /**
148 * Allows for additional processing of the product IDs after they have been queued.
149 *
150 * @since 10.2.0
151 *
152 * @param array $product_ids The product IDs to process.
153 */
154 do_action( 'woocommerce_customer_stock_notifications_product_sync', $product_ids );
155 $this->queue = array();
156 }
157
158 /**
159 * Store the admin notice.
160 *
161 * @param int $product_id The product ID to sync.
162 * @return void
163 */
164 private function store_admin_notice( $product_id ): void {
165 if ( ! is_admin() || ! function_exists( 'wp_admin_notice' ) ) {
166 return;
167 }
168
169 /* translators: 1 = URL of the Back in Stock Notifications page */
170 $notice_message = sprintf( __( 'Back-in-stock notifications for this product are now being processed. Subscribed customers will receive these emails over the next few minutes. You can monitor or manage individual subscriptions on the <a href="%s">Stock Notifications page</a>.', 'woocommerce' ), sprintf( admin_url( 'admin.php?page=wc-customer-stock-notifications&customer_stock_notifications_product_filter=%d&status=active_customer_stock_notifications&filter_action=Filter' ), $product_id ) );
171
172 update_option( 'wc_customer_stock_notifications_product_sync_notice', $notice_message );
173 }
174
175 /**
176 * Add admin notices.
177 *
178 * @return void
179 */
180 public function output_admin_notice(): void {
181 if ( ! function_exists( 'wp_admin_notice' ) ) {
182 return;
183 }
184
185 $notice_message = get_option( 'wc_customer_stock_notifications_product_sync_notice' );
186 if ( empty( $notice_message ) ) {
187 return;
188 }
189
190 \wp_admin_notice(
191 $notice_message,
192 array(
193 'type' => 'info',
194 'id' => 'woocommerce_customer_stock_notifications_product_sync_notice',
195 'dismissible' => false,
196 )
197 );
198
199 delete_option( 'wc_customer_stock_notifications_product_sync_notice' );
200 }
201 }
202