PluginProbe ʕ •ᴥ•ʔ
WooCommerce Square / 5.4.0
WooCommerce Square v5.4.0
5.4.1 5.4.0 trunk 1.0.25 1.0.26 1.0.27 1.0.28 1.0.29 1.0.30 1.0.31 1.0.32 1.0.33 1.0.34 1.0.35 1.0.36 1.0.37 1.0.38 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.3.0 2.3.1 2.3.2 2.3.3 2.3.4 2.4.0 2.4.1 2.5.0 2.5.1 2.5.2 2.5.3 2.6.0 2.7.0 2.8.0 2.9.0 2.9.1 3.0.0 3.0.1 3.0.2 3.0.3 3.1.0 3.2.0 3.3.0 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.6.1 3.7.0 3.7.1 3.8.0 3.8.1 3.8.2 3.8.3 3.9.0 4.0.0 4.1.0 4.2.0 4.2.1 4.2.2 4.2.3 4.3.0 4.3.1 4.3.2 4.4.0 4.4.1 4.4.2 4.5.0 4.5.1 4.5.2 4.6.0 4.6.1 4.6.2 4.6.3 4.6.4 4.7.0 4.7.1 4.7.2 4.7.3 4.7.4 4.8.0 4.8.1 4.8.2 4.8.3 4.8.4 4.8.5 4.8.6 4.8.7 4.8.8 4.9.0 4.9.1 4.9.2 4.9.3 4.9.4 4.9.5 4.9.6 4.9.7 4.9.8 4.9.9 5.0.0 5.0.1 5.1.0 5.1.1 5.1.2 5.2.0 5.3.0 5.3.1 5.3.2 5.3.3
woocommerce-square / includes / Admin.php
woocommerce-square / includes Last commit date
API 3 months ago Admin 3 months ago Emails 1 year ago Framework 1 month ago Gateway 1 month ago Handlers 1 month ago Internal 1 month ago Sync 1 month ago Utilities 1 month ago AJAX.php 2 years ago API.php 1 month ago Admin.php 1 month ago Coupons.php 3 months ago Functions.php 3 years ago Gateway.php 2 months ago Lifecycle.php 2 years ago Plugin.php 1 month ago Settings.php 3 months ago WC_Order_Square.php 2 years ago WC_Payments_Compatibility.php 1 year ago
Admin.php
471 lines
1 <?php
2 /**
3 * WooCommerce Square
4 *
5 * This source file is subject to the GNU General Public License v3.0
6 * that is bundled with this package in the file license.txt.
7 * It is also available through the world-wide-web at this URL:
8 * http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0 or later
9 * If you did not receive a copy of the license and are unable to
10 * obtain it through the world-wide-web, please send an email
11 * to license@woocommerce.com so we can send you a copy immediately.
12 *
13 * DISCLAIMER
14 *
15 * Do not edit or add to this file if you wish to upgrade WooCommerce Square to newer
16 * versions in the future. If you wish to customize WooCommerce Square for your
17 * needs please refer to https://docs.woocommerce.com/document/woocommerce-square/
18 *
19 * @author WooCommerce
20 * @copyright Copyright: (c) 2019, Automattic, Inc.
21 * @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0 or later
22 */
23
24 namespace WooCommerce\Square;
25
26 defined( 'ABSPATH' ) || exit;
27
28 use WooCommerce\Square\Admin\Analytics\Revenue;
29 use WooCommerce\Square\Handlers\Products;
30 use WooCommerce\Square\Handlers\Product;
31
32 /**
33 * The base admin handler class.
34 *
35 * @since 2.0.0
36 */
37 class Admin {
38
39
40 /**
41 * Product handler.
42 *
43 * @var Handlers\Products
44 */
45 private $products_handler;
46
47 /**
48 * Privacy handler.
49 *
50 * @var Admin\Privacy
51 */
52 private $privacy_handler;
53
54 /**
55 * Plugin
56 *
57 * @var Plugin plugin instance
58 */
59 private $plugin;
60
61
62 /**
63 * Constructs the class.
64 *
65 * @since 2.0.0
66 *
67 * @param Plugin $plugin plugin instance.
68 */
69 public function __construct( Plugin $plugin ) {
70
71 $this->plugin = $plugin;
72
73 $this->products_handler = $this->plugin->get_products_handler();
74
75 // privacy
76 $this->privacy_handler = new Admin\Privacy();
77
78 new Revenue();
79
80 $this->add_hooks();
81 }
82
83
84 /**
85 * Adds the action & filter hooks.
86 *
87 * @since 2.0.0
88 */
89 private function add_hooks() {
90
91 // add the settings page.
92 add_filter(
93 'woocommerce_get_settings_pages',
94 function ( $pages ) {
95
96 $pages[] = new Admin\Settings_Page( $this->get_plugin()->get_settings_handler() );
97
98 return $pages;
99 }
100 );
101
102 // load admin scripts.
103 add_action(
104 'admin_enqueue_scripts',
105 function ( $hook ) {
106 $this->load_scripts_styles( $hook );
107 }
108 );
109
110 // Show warning notice for the user to manually trigger a sync if it has been a while since the last successful sync.
111 add_action( 'admin_notices', array( $this, 'maybe_show_sync_status_notice' ) );
112 }
113
114
115 /**
116 * Loads and enqueues admin scripts and styles.
117 *
118 * @param string $hook The current admin page.
119 *
120 * @since 2.0.0
121 */
122 private function load_scripts_styles( $hook ) {
123 global $typenow;
124
125 if ( 'product' === $typenow ) {
126
127 wp_enqueue_script(
128 'wc-square-admin-products',
129 $this->get_plugin()->get_plugin_url() . '/build/assets/admin/wc-square-admin-products.js',
130 array( 'jquery' ),
131 Plugin::VERSION,
132 true
133 );
134
135 wp_enqueue_style(
136 'wc-square-admin-products',
137 $this->get_plugin()->get_plugin_url() . '/build/assets/admin/wc-square-admin-products-styles.css',
138 array(),
139 Plugin::VERSION
140 );
141
142 wp_localize_script(
143 'wc-square-admin-products',
144 'wc_square_admin_products',
145 array(
146 'ajax_url' => admin_url( 'admin-ajax.php' ),
147 'settings_url' => esc_url( $this->get_plugin()->get_settings_url() ),
148 'variable_product_types' => $this->get_variable_product_types(),
149 'synced_with_square_taxonomy' => Product::SYNCED_WITH_SQUARE_TAXONOMY,
150 'is_product_sync_enabled' => $this->get_plugin()->get_settings_handler()->is_product_sync_enabled(),
151 'is_woocommerce_sor' => $this->get_plugin()->get_settings_handler()->is_system_of_record_woocommerce(),
152 'is_square_sor' => $this->get_plugin()->get_settings_handler()->is_system_of_record_square(),
153 'is_inventory_sync_enabled' => $this->get_plugin()->get_settings_handler()->is_inventory_sync_enabled(),
154 'get_quick_edit_product_details_nonce' => wp_create_nonce( 'get-quick-edit-product-details' ),
155 'fetch_product_stock_with_square_nonce' => wp_create_nonce( 'fetch-product-stock-with-square' ),
156 'supported_products_for_sync' => array( 'simple', 'variable' ),
157 'i18n' => array(
158 'inventory_tracking_disabled' => __( 'Inventory tracking is disabled for this product', 'woocommerce-square' ),
159 'synced_with_square' => __( 'Synced with Square', 'woocommerce-square' ),
160 'managed_by_square' => __( 'Managed by Square', 'woocommerce-square' ),
161 'fetch_stock_with_square' => __( 'Fetch stock from Square', 'woocommerce-square' ),
162 'sync_inventory' => __( 'Sync inventory', 'woocommerce-square' ),
163 'sync_stock_from_square' => __( 'Sync stock from Square', 'woocommerce-square' ),
164 'attribute_name_too_long' => __( 'Attribute name is too long, maximum allowed are 65 characters', 'woocommerce-square' ),
165 'too_many_attributes' => __( 'Too many attributes, maximum allowed are 6.', 'woocommerce-square' ),
166 /* translators: %d - maximum allowed attribute values */
167 'too_many_attribute_values' => __( 'Too many attribute values: %d (max 250)', 'woocommerce-square' ),
168 'too_many_variations' => __( 'Too many variations, maximum allowed are 250.', 'woocommerce-square' ),
169 ),
170 )
171 );
172 } elseif ( $this->get_plugin()->is_plugin_settings() ) {
173 wp_enqueue_style(
174 'wc-square-admin',
175 $this->get_plugin()->get_plugin_url() . '/build/assets/admin/wc-square-admin.css',
176 array(),
177 Plugin::VERSION
178 );
179
180 wp_enqueue_media();
181
182 wp_enqueue_script(
183 'wc-square-admin-settings',
184 $this->get_plugin()->get_plugin_url() . '/build/assets/admin/wc-square-admin-settings.js',
185 array( 'jquery', 'jquery-blockui', 'backbone', 'wc-backbone-modal' ),
186 Plugin::VERSION,
187 true
188 );
189
190 $sync_job = $this->get_plugin()->get_sync_handler()->get_job_in_progress();
191
192 if ( $sync_job ) {
193 $existing_sync_id = $sync_job->id;
194 } else {
195 $existing_sync_id = false;
196 }
197
198 wp_localize_script(
199 'wc-square-admin-settings',
200 'wc_square_admin_settings',
201 array(
202 'ajax_url' => admin_url( 'admin-ajax.php' ),
203 'is_product_sync_enabled' => $this->get_plugin()->get_settings_handler()->is_product_sync_enabled(),
204 'is_woocommerce_sor' => $this->get_plugin()->get_settings_handler()->is_system_of_record_woocommerce(),
205 'is_square_sor' => $this->get_plugin()->get_settings_handler()->is_system_of_record_square(),
206 'is_inventory_sync_enabled' => $this->get_plugin()->get_settings_handler()->is_inventory_sync_enabled(),
207 'is_sandbox' => $this->get_plugin()->get_settings_handler()->is_sandbox(),
208 'existing_sync_job_id' => $existing_sync_id,
209 'import_products_from_square' => wp_create_nonce( 'import-products-from-square' ),
210 'sync_products_with_square' => wp_create_nonce( 'sync-products-with-square' ),
211 'get_sync_with_square_status_nonce' => wp_create_nonce( 'get-sync-with-square-status' ),
212 'handle_sync_with_square_records' => wp_create_nonce( 'handle-sync-with-square-records' ),
213 'i18n' => array(
214 'resolved' => __( 'Resolved', 'woocommerce-square' ),
215 'no_records_found' => __( 'No records found', 'woocommerce-square' ),
216 'skipped' => __( 'Skipped', 'woocommerce-square' ),
217 'updated' => __( 'Updated', 'woocommerce-square' ),
218 'imported' => __( 'Imported', 'woocommerce-square' ),
219 'sync_inventory_label' => array(
220 'square' => __( 'Enable to fetch inventory changes from Square', 'woocommerce-square' ),
221 'woocommerce' => __( 'Enable to push inventory changes to Square', 'woocommerce-square' ),
222 ),
223 'sync_inventory_description' => array(
224 'square' => __( 'Inventory is fetched from Square periodically and updated in WooCommerce', 'woocommerce-square' ),
225 'woocommerce' => sprintf(
226 /* translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag */
227 __( 'Inventory is %1$salways fetched from Square%2$s periodically to account for sales from other channels.', 'woocommerce-square' ),
228 '<strong>',
229 '</strong>'
230 ),
231 ),
232 ),
233 )
234 );
235
236 $asset_file = WC_SQUARE_PLUGIN_PATH . 'build/settings.asset.php';
237
238 if ( ! file_exists( $asset_file ) ) {
239 return;
240 }
241
242 $asset = include $asset_file;
243
244 wp_enqueue_script(
245 'woocommerce-square-settings-js',
246 WC_SQUARE_PLUGIN_URL . 'build/settings.js',
247 $asset['dependencies'],
248 $asset['version'],
249 array(
250 'in_footer' => true,
251 )
252 );
253
254 $gift_card_placeholder_url = Products::get_gift_card_default_placeholder_url();
255
256 if ( empty( $gift_card_placeholder_url ) ) {
257 $gift_card_placeholder_url = WC_SQUARE_PLUGIN_URL . 'build/images/gift-card-featured-image.png';
258 }
259
260 wp_localize_script(
261 'woocommerce-square-settings-js',
262 'wcSquareSettings',
263 array(
264 'nonce' => wp_create_nonce( 'wc_square_settings' ),
265 'homeUrl' => home_url(),
266 'adminUrl' => admin_url(),
267 'ajaxUrl' => admin_url( 'admin-ajax.php' ),
268 'depsCheck' => $this->get_plugin()->get_dependency_handler()->meets_php_dependencies(),
269 'gcPlaceholderUrl' => esc_url( $gift_card_placeholder_url ),
270 )
271 );
272
273 wp_enqueue_style(
274 'woocommerce-square-settings-css',
275 WC_SQUARE_PLUGIN_URL . 'build/settings.css',
276 array(),
277 $asset['version'],
278 );
279 } elseif ( 'woocommerce_page_woocommerce-square-onboarding' === $hook ) {
280 $asset_file = WC_SQUARE_PLUGIN_PATH . 'build/onboarding.asset.php';
281
282 if ( ! file_exists( $asset_file ) ) {
283 return;
284 }
285
286 $asset = include $asset_file;
287
288 wp_enqueue_script(
289 'woocommerce-square-onboarding-js',
290 WC_SQUARE_PLUGIN_URL . 'build/onboarding.js',
291 $asset['dependencies'],
292 $asset['version'],
293 array(
294 'in_footer' => true,
295 )
296 );
297
298 wp_localize_script(
299 'woocommerce-square-onboarding-js',
300 'wcSquareSettings',
301 array(
302 'nonce' => wp_create_nonce( 'wc_square_settings' ),
303 'homeUrl' => home_url(),
304 'adminUrl' => admin_url(),
305 'ajaxUrl' => admin_url( 'admin-ajax.php' ),
306 )
307 );
308
309 wp_enqueue_style(
310 'woocommerce-square-onboarding-css',
311 WC_SQUARE_PLUGIN_URL . 'build/onboarding.css',
312 array(),
313 $asset['version'],
314 );
315
316 wp_localize_script(
317 'woocommerce-square-onboarding-js',
318 'wcSquareOnboarding',
319 array(
320 'plugin_version' => WC_SQUARE_PLUGIN_VERSION,
321 'is_mobile' => wp_is_mobile(),
322 )
323 );
324 }
325
326 wp_enqueue_style( 'wp-components' );
327 }
328
329
330 /**
331 * Gets a list of variable product types.
332 *
333 * @since 2.0.0
334 *
335 * @return string[]
336 */
337 private function get_variable_product_types() {
338
339 /**
340 * Filters the variable product types.
341 *
342 * @since 2.0.0
343 *
344 * @param string[] array of product types
345 */
346 return (array) apply_filters( 'wc_square_variable_product_types', array( 'variable', 'variable-subscription' ) );
347 }
348
349
350 /**
351 * Gets the products handler.
352 *
353 * @since 2.0.0
354 *
355 * @return Admin\Products
356 */
357 public function get_products_handler() {
358
359 return $this->products_handler;
360 }
361
362
363 /**
364 * Gets the plugin instance.
365 *
366 * @since 2.0.0
367 *
368 * @return Plugin
369 */
370 protected function get_plugin() {
371
372 return $this->plugin;
373 }
374
375 /**
376 * Maybe show a warning notice for the user to manually trigger a sync if it has been a while since the last successful sync.
377 *
378 * If the following conditions are met, show the notice:
379 * - The connection is established.
380 * - The location is set.
381 * - The product sync is enabled.
382 * - The last synced at is set and is before the threshold time (default is 24 hours, 48 hours if the sync interval is 24 hours).
383 * - The synced products count is greater than 0 (at least one product is synced with Square).
384 *
385 * @since 5.3.3
386 *
387 * @return void
388 */
389 public function maybe_show_sync_status_notice() {
390 // Bail if the user does not have the manage_woocommerce capability.
391 if ( ! current_user_can( 'manage_woocommerce' ) ) { // phpcs:ignore WordPress.WP.Capabilities.Unknown
392 return;
393 }
394
395 // Bail if the connection is not established, the location is not set, or the product sync is not enabled.
396 $is_connected = wc_square()->get_settings_handler()->is_connected();
397 $location_id = wc_square()->get_settings_handler()->get_location_id();
398 $is_product_sync_enabled = wc_square()->get_settings_handler()->is_product_sync_enabled();
399 if ( ! $is_connected || ! $location_id || ! $is_product_sync_enabled ) {
400 return;
401 }
402
403 // Bail if the last synced at is not set.
404 $last_synced_at = wc_square()->get_sync_handler()->get_last_synced_at();
405 if ( ! $last_synced_at ) {
406 return;
407 }
408
409 // The threshold time is 24 hours by default, 48 hours if the sync interval is 24 hours.
410 $sync_interval = wc_square()->get_settings_handler()->get_sync_interval();
411 $threshold_seconds = $sync_interval >= 24 * HOUR_IN_SECONDS ? 48 * HOUR_IN_SECONDS : 24 * HOUR_IN_SECONDS;
412
413 /**
414 * Filters the threshold time for the sync status notice.
415 *
416 * @since 5.3.3
417 *
418 * @param int $threshold_seconds The threshold time in seconds. Default is 24 hours, or 48 hours when the sync interval is 24 hours.
419 * @param int $sync_interval The sync interval in seconds.
420 */
421 $threshold_seconds = apply_filters( 'wc_square_sync_status_notice_threshold_seconds', $threshold_seconds, $sync_interval );
422 $threshold_time = time() - $threshold_seconds;
423
424 // Bail if the last synced at is after the threshold time.
425 if ( $last_synced_at > $threshold_time ) {
426 return;
427 }
428
429 // Get the synced products count.
430 $synced_products_count_key = 'wc_square_synced_products_count_' . $location_id;
431 $synced_products_count = get_transient( $synced_products_count_key );
432
433 if ( false === $synced_products_count ) {
434 $synced_products_count = count( Product::get_products_synced_with_square() );
435
436 // Set the transient for the synced products count.
437 set_transient( $synced_products_count_key, $synced_products_count, $threshold_seconds );
438 }
439
440 // Bail if synced products count is 0.
441 if ( 0 === (int) $synced_products_count ) {
442 return;
443 }
444
445 // Show the notice if the last synced at is before the threshold time.
446 ?>
447 <div class="notice notice-warning is-dismissible">
448 <p>
449 <?php
450 echo wp_kses(
451 sprintf(
452 /* translators: Placeholders: %1$s - <a> tag, %2$s - </a> tag, %3$s - <a> tag, %4$s - </a> tag */
453 __( 'It has been a while since the last successful sync. Please manually trigger a sync from the %1$supdate page%2$s, or clear the ongoing sync from the %3$stools page%4$s if it is stuck, to ensure that your products are up to date.', 'woocommerce-square' ),
454 '<a href="' . esc_url( admin_url( 'admin.php?page=wc-settings&tab=square&section=update' ) ) . '">',
455 '</a>',
456 '<a href="' . esc_url( admin_url( 'admin.php?page=wc-status&tab=tools' ) ) . '">',
457 '</a>'
458 ),
459 array(
460 'a' => array(
461 'href' => array(),
462 ),
463 )
464 );
465 ?>
466 </p>
467 </div>
468 <?php
469 }
470 }
471