PluginProbe
WooCommerce Square / 4.9.6
WooCommerce Square v4.9.6
5.5.0 5.4.3 5.4.2 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 All 132 releases
woocommerce-square / woocommerce-square.php
woocommerce-square.php
521 lines 14.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Plugin Name: WooCommerce Square
4 * Requires Plugins: woocommerce
5 * Version: 4.9.6
6 * Plugin URI: https://woocommerce.com/products/square/
7 * Requires at least: 6.6
8 * Tested up to: 6.8
9 * Requires PHP: 7.4
10 * PHP tested up to: 8.3
11 *
12 * Description: Securely accept payments, synchronize sales, and seamlessly manage inventory and product data between WooCommerce and Square POS.
13 * Author: WooCommerce
14 * Author URI: https://www.woocommerce.com/
15 * Text Domain: woocommerce-square
16 * Domain Path: /i18n/languages/
17 *
18 * License: GPL-3.0-or-later
19 * License URI: http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0 or later
20 *
21 * @author WooCommerce
22 * @copyright Copyright (c) 2019, Automattic, Inc.
23 * @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0 or later
24 *
25 * WC requires at least: 9.8
26 * WC tested up to: 10.0
27 */
28
29 defined( 'ABSPATH' ) || exit;
30
31 if ( ! defined( 'WC_SQUARE_PLUGIN_VERSION' ) ) {
32 define( 'WC_SQUARE_PLUGIN_VERSION', '4.9.6' ); // WRCS: DEFINED_VERSION.
33 }
34
35 if ( ! defined( 'WC_SQUARE_PLUGIN_URL' ) ) {
36 define( 'WC_SQUARE_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
37 }
38
39 if ( ! defined( 'WC_SQUARE_PLUGIN_PATH' ) ) {
40 define( 'WC_SQUARE_PLUGIN_PATH', plugin_dir_path( __FILE__ ) );
41 }
42
43 if ( ! defined( 'WC_SQUARE_OPTION_ANY' ) ) {
44 define( 'WC_SQUARE_OPTION_ANY', 'Any' );
45 }
46
47 /**
48 * The plugin loader class.
49 *
50 * @since 2.0.0
51 */
52 class WooCommerce_Square_Loader {
53
54
55 /** minimum PHP version required by this plugin */
56 const MINIMUM_PHP_VERSION = '7.4.0';
57
58 /** minimum WordPress version required by this plugin */
59 const MINIMUM_WP_VERSION = '6.6';
60
61 /** minimum WooCommerce version required by this plugin */
62 const MINIMUM_WC_VERSION = '9.7';
63
64 /**
65 * SkyVerge plugin framework version used by this plugin
66 * Constant is left as it is for legacy purposes.
67 **/
68 const FRAMEWORK_VERSION = '5.4.0';
69
70 /** the plugin name, for displaying notices */
71 const PLUGIN_NAME = 'Square for WooCommerce';
72
73
74 /** @var WooCommerce_Square_Loader single instance of this class */
75 private static $instance;
76
77 /** @var array the admin notices to add */
78 private $notices = array();
79
80
81 /**
82 * Constructs the class.
83 *
84 * @since 2.0.0
85 */
86 protected function __construct() {
87 add_action( 'admin_notices', array( $this, 'admin_notices' ), 15 );
88 add_action( 'before_woocommerce_init', array( $this, 'declare_features_compatibility' ) );
89 /*
90 * Bootstrap the extension on plugins_loaded.
91 *
92 * This ensures that the extension is loaded after WooCommerce Core and to
93 * ensure the WC_VERSION constant is defined prior to checking for compatibility.
94 */
95 add_action( 'plugins_loaded', array( $this, 'init_plugin' ) );
96 }
97
98
99 /**
100 * Cloning instances is forbidden due to singleton pattern.
101 *
102 * @since 2.0.0
103 */
104 public function __clone() {
105
106 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
107 _doing_it_wrong( __FUNCTION__, sprintf( 'You cannot clone instances of %s.', get_class( $this ) ), '2.0.0' );
108 }
109
110
111 /**
112 * Unserializing instances is forbidden due to singleton pattern.
113 *
114 * @since 2.0.0
115 */
116 public function __wakeup() {
117
118 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
119 _doing_it_wrong( __FUNCTION__, sprintf( 'You cannot unserialize instances of %s.', get_class( $this ) ), '2.0.0' );
120 }
121
122
123 /**
124 * Initializes the plugin.
125 *
126 * @since 2.0.0
127 */
128 public function init_plugin() {
129
130 if ( ! $this->is_environment_compatible() ) {
131 return;
132 }
133
134 $this->load_framework();
135
136 // autoload plugin and vendor files
137 $loader = require_once plugin_dir_path( __FILE__ ) . 'vendor/autoload.php';
138
139 // register plugin namespace with autoloader
140 $loader->addPsr4( 'WooCommerce\\Square\\', __DIR__ . '/includes' );
141
142 require_once plugin_dir_path( __FILE__ ) . 'includes/Functions.php';
143
144 // fire it up!
145 wc_square();
146
147 add_action( 'woocommerce_blocks_payment_method_type_registration', array( $this, 'register_payment_method_block_integrations' ), 5, 1 );
148 }
149
150
151 /**
152 * Loads the base framework classes.
153 *
154 * @since 2.0.0
155 */
156 protected function load_framework() {
157 require_once plugin_dir_path( __FILE__ ) . 'includes/Framework/Plugin.php';
158 require_once plugin_dir_path( __FILE__ ) . 'includes/Framework/PaymentGateway/Payment_Gateway_Plugin.php';
159 }
160
161
162 /**
163 * Gets the framework version in namespace form.
164 *
165 * @since 2.0.0
166 *
167 * @return string
168 */
169 protected function get_framework_version_namespace() {
170
171 return 'v' . str_replace( '.', '_', $this->get_framework_version() );
172 }
173
174
175 /**
176 * Gets the framework version used by this plugin.
177 *
178 * @since 2.0.0
179 *
180 * @return string
181 */
182 protected function get_framework_version() {
183
184 return self::FRAMEWORK_VERSION;
185 }
186
187 /**
188 * Adds notices for out-of-date WordPress and/or WooCommerce versions.
189 *
190 * @since 2.0.0
191 * @deprecated 4.6.3 Use \WooCommerce_Square_Loader::is_environment_compatible() instead.
192 */
193 public function add_plugin_notices() {
194 _deprecated_function( __METHOD__, '4.6.3', '\WooCommerce_Square_Loader::is_environment_compatible()' );
195 $this->is_environment_compatible();
196 }
197
198
199 /**
200 * Determines if the required plugins are compatible.
201 *
202 * @since 2.0.0
203 * @deprecated 4.6.3 Use \WooCommerce_Square_Loader::is_environment_compatible() instead.
204 *
205 * @return bool
206 */
207 protected function plugins_compatible() {
208 _deprecated_function( __METHOD__, '4.6.3', '\WooCommerce_Square_Loader::is_environment_compatible()' );
209 return $this->is_environment_compatible();
210 }
211
212
213 /**
214 * Determines if the WordPress compatible.
215 *
216 * @since 2.0.0
217 *
218 * @return bool
219 */
220 protected function is_wp_compatible() {
221
222 if ( ! self::MINIMUM_WP_VERSION ) {
223 return true;
224 }
225
226 return version_compare( get_bloginfo( 'version' ), self::MINIMUM_WP_VERSION, '>=' );
227 }
228
229
230 /**
231 * Determines if the WooCommerce compatible.
232 *
233 * @since 2.0.0
234 *
235 * @return bool
236 */
237 protected function is_wc_compatible() {
238
239 if ( ! self::MINIMUM_WC_VERSION ) {
240 return true;
241 }
242
243 return defined( 'WC_VERSION' ) && version_compare( WC_VERSION, self::MINIMUM_WC_VERSION, '>=' );
244 }
245
246
247 /**
248 * Deactivates the plugin.
249 *
250 * @since 2.0.0
251 */
252 protected function deactivate_plugin() {
253
254 deactivate_plugins( plugin_basename( __FILE__ ) );
255
256 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
257 if ( isset( $_GET['activate'] ) ) {
258 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
259 unset( $_GET['activate'] );
260 }
261 }
262
263
264 /**
265 * Adds an admin notice to be displayed.
266 *
267 * @since 2.0.0
268 *
269 * @param string $slug the slug for the notice
270 * @param string $class the css class for the notice
271 * @param string $message the notice message
272 */
273 public function add_admin_notice( $slug, $class, $message ) {
274
275 $this->notices[ $slug ] = array(
276 'class' => $class,
277 'message' => $message,
278 );
279 }
280
281
282 /**
283 * Displays any admin notices added with \WooCommerce_Square_Loader::add_admin_notice()
284 *
285 * @since 2.0.0
286 */
287 public function admin_notices() {
288
289 foreach ( (array) $this->notices as $notice_key => $notice ) {
290
291 ?>
292 <div class="<?php echo esc_attr( $notice['class'] ); ?>">
293 <p>
294 <?php
295 echo wp_kses(
296 $notice['message'],
297 array(
298 'a' => array(
299 'href' => array(),
300 'target' => array(),
301 ),
302 'code' => array(),
303 'strong' => array(),
304 'br' => array(),
305 )
306 );
307 ?>
308 </p>
309 </div>
310 <?php
311 }
312 }
313
314
315 /**
316 * Determines if the server environment is compatible with this plugin.
317 *
318 * Override this method to add checks for more than just the PHP version.
319 *
320 * @since 2.0.0
321 *
322 * @return bool
323 */
324 public function is_environment_compatible() {
325 $is_wc_compatible = $this->is_wc_compatible();
326 $is_wp_compatible = $this->is_wp_compatible();
327 $is_php_valid = $this->is_php_version_valid();
328 $is_opcache_config_valid = $this->is_opcache_save_message_enabled();
329 $error_message = '';
330
331 if ( ! $is_php_valid || ! $is_opcache_config_valid || ! $is_wc_compatible || ! $is_wp_compatible ) {
332 $error_message .= sprintf(
333 // translators: plugin name
334 __( '<strong>All features in %1$s have been disabled</strong> due to unsupported settings:<br>', 'woocommerce-square' ),
335 self::PLUGIN_NAME
336 );
337 }
338
339 if ( ! $is_php_valid ) {
340 $error_message .= sprintf(
341 // translators: minimum PHP version, current PHP version
342 __( '&bull;&nbsp;<strong>Invalid PHP version: </strong>The minimum PHP version required is %1$s. You are running %2$s.<br>', 'woocommerce-square' ),
343 self::MINIMUM_PHP_VERSION,
344 PHP_VERSION
345 );
346 }
347
348 if ( ! $is_opcache_config_valid ) {
349 $error_message .= sprintf(
350 // translators: link to documentation
351 __( '&bull;&nbsp;<strong>Invalid OPcache config: </strong><a href="%s" target="_blank">Please ensure the <code>save_comments</code> PHP option is enabled.</a> You may need to contact your hosting provider to change caching options.', 'woocommerce-square' ),
352 'https://woocommerce.com/document/woocommerce-square/troubleshooting/#section-3'
353 );
354 }
355
356 if ( ! $is_wc_compatible ) {
357 if ( ! defined( 'WC_VERSION' ) ) {
358 $error_message .= sprintf(
359 // translators: 1: Minimum required WooCommerce version.
360 __( '&bull;&nbsp;<strong>WooCommerce is not installed: </strong>The plugin requires WooCommerce version %1$s or later be installed.<br>', 'woocommerce-square' ),
361 self::MINIMUM_WC_VERSION
362 );
363 } else {
364 $error_message .= sprintf(
365 // translators: 1: Plugin name, 2: Minimum required WooCommerce version, 3: Opening link to upgrade screen, 4: Closing link, 5: Opening link to download page, 6: Closing link.
366 '&bull;&nbsp;%1$s requires WooCommerce version %2$s or higher. Please %3$supdate WooCommerce%4$s to the latest version, or %5$sdownload the minimum required version &raquo;%6$s<br>',
367 '<strong>' . self::PLUGIN_NAME . '</strong>',
368 self::MINIMUM_WC_VERSION,
369 '<a href="' . esc_url( admin_url( 'update-core.php' ) ) . '">',
370 '</a>',
371 '<a href="' . esc_url( $this->get_woocommerce_download_link( 'minimum' ) ) . '">',
372 '</a>'
373 );
374 }
375 }
376
377 if ( ! $is_wp_compatible ) {
378 $error_message .= sprintf(
379 // translators: 1: Plugin name, 2: Minimum required WordPress version, 3: Opening link to upgrade screen, 4: Closing link.
380 '&bull;&nbsp;%s requires WordPress version %s or higher. Please %supdate WordPress &raquo;%s<br>',
381 '<strong>' . self::PLUGIN_NAME . '</strong>',
382 self::MINIMUM_WP_VERSION,
383 '<a href="' . esc_url( admin_url( 'update-core.php' ) ) . '">',
384 '</a>'
385 );
386 }
387
388 if ( ! empty( $error_message ) ) {
389 $this->add_admin_notice(
390 'bad_environment',
391 'error',
392 $error_message
393 );
394 }
395
396 return $is_php_valid && $is_opcache_config_valid && $is_wc_compatible && $is_wp_compatible;
397 }
398
399 /**
400 * Get the WooCommerce download link for a specific version.
401 *
402 * Ensures the download link is correct for major versions of WooCommerce by
403 * ensuring that specific download links match the tagged version and include
404 * three parts in the version number.
405 *
406 * @since 4.6.3
407 *
408 * @param string|int|float $version The version of WooCommerce to get the download link for.
409 * Accepts a version number in the forms of 'x', 'x.x' or 'x.x.x'.
410 * Accepts the strings 'minimum' and 'latest'.
411 * Defaults to 'latest'.
412 * @return string The download link for the WooCommerce version.
413 */
414 public function get_woocommerce_download_link( $version = 'latest' ) {
415 $version = (string) $version;
416 $version = strtolower( $version );
417
418 if ( preg_match( '/^(\d+\.)*(\d+)$/', $version ) || 'minimum' === $version ) {
419 if ( 'minimum' === $version ) {
420 $version_download_string = self::MINIMUM_WC_VERSION;
421 } else {
422 $version_download_string = $version;
423 }
424 $version_parts = explode( '.', $version_download_string );
425 /*
426 * Ensure the version string has at least 3 parts.
427 *
428 * Publicly major versions are listed as two parts, eg 6.7, but the
429 * tag published to the WordPress.org repository uses three parts,
430 * eg 6.7.0.
431 *
432 * This is to ensure the download link is correct.
433 */
434 $version_part_count = count( $version_parts ); // Coding standards don't allow for count() in the while condition.
435 while ( $version_part_count < 3 ) {
436 $version_parts[] = '0';
437 $version_part_count = count( $version_parts );
438 }
439 $version_download_string = implode( '.', $version_parts );
440 } else {
441 // Default to latest version.
442 $version_download_string = 'latest-stable';
443 }
444
445 return "https://downloads.wordpress.org/plugin/woocommerce.{$version_download_string}.zip";
446 }
447
448 /**
449 * Declares support for WooCommerce features.
450 */
451 public function declare_features_compatibility() {
452 if ( class_exists( '\Automattic\WooCommerce\Utilities\FeaturesUtil' ) ) {
453 \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', __FILE__, true );
454
455 new \WooCommerce\Square\Admin\Product_Editor_Compatibility();
456 }
457 }
458
459 /**
460 * Returns true if opcache.save_comments is enabled.
461 *
462 * @since 3.0.2
463 *
464 * @return boolean
465 */
466 protected function is_opcache_save_message_enabled() {
467 $zend_optimizer_plus = extension_loaded( 'Zend Optimizer+' ) && '0' === ( ini_get( 'zend_optimizerplus.save_comments' ) || '0' === ini_get( 'opcache.save_comments' ) );
468 $zend_opcache = extension_loaded( 'Zend OPcache' ) && '0' === ini_get( 'opcache.save_comments' );
469
470 return ! ( $zend_optimizer_plus || $zend_opcache );
471 }
472
473 /**
474 * Returns true if the PHP version of the environment
475 * meets the requirement.
476 *
477 * @since 3.0.2
478 *
479 * @return boolean
480 */
481 protected function is_php_version_valid() {
482 return version_compare( PHP_VERSION, self::MINIMUM_PHP_VERSION, '>=' );
483 }
484
485 /**
486 * Register the Square Credit Card checkout block integration class
487 *
488 * @since 2.5.0
489 */
490 public function register_payment_method_block_integrations( $payment_method_registry ) {
491 if ( class_exists( '\Automattic\WooCommerce\Blocks\Payments\Integrations\AbstractPaymentMethodType' ) ) {
492 $payment_method_registry->register( new WooCommerce\Square\Gateway\Blocks_Handler() );
493 $payment_method_registry->register( new WooCommerce\Square\Gateway\Cash_App_Pay_Blocks_Handler() );
494 }
495 }
496
497
498 /**
499 * Gets the main plugin loader instance.
500 *
501 * Ensures only one instance can be loaded.
502 *
503 * @since 2.0.0
504 *
505 * @return \WooCommerce_Square_Loader
506 */
507 public static function instance() {
508
509 if ( null === self::$instance ) {
510 self::$instance = new self();
511 }
512
513 return self::$instance;
514 }
515
516
517 }
518
519 // fire it up!
520 WooCommerce_Square_Loader::instance();
521