PluginProbe ʕ •ᴥ•ʔ
TaxCloud for WooCommerce / 8.4.11
TaxCloud for WooCommerce v8.4.11
8.4.11 8.4.10 8.4.9 trunk 6.0.11 6.0.12 6.0.13 6.0.14 6.1.0 6.1.1 6.1.2 6.2.0 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.2.6 6.3.0 6.3.1 6.3.10 6.3.11 6.3.12 6.3.13 6.3.2 6.3.3 6.3.4 6.3.5 6.3.6 6.3.7 6.3.8 6.3.9 7.0.0 7.0.1 7.0.10 7.0.11 7.0.12 7.0.13 7.0.2 7.0.3 7.0.4 7.0.5 7.0.6 7.0.7 7.0.8 7.0.9 8.0.0 8.0.1 8.0.10 8.0.11 8.0.12 8.0.13 8.0.14 8.0.15 8.0.16 8.0.17 8.0.2 8.0.3 8.0.4 8.0.5 8.0.6 8.0.7 8.0.8 8.0.9 8.1.0 8.1.1 8.2.0 8.2.1 8.2.2 8.2.3 8.2.4 8.3.0 8.3.1 8.3.2 8.3.3 8.3.4 8.3.5 8.3.6 8.3.7 8.3.8 8.4.0 8.4.1 8.4.2 8.4.3 8.4.4 8.4.5 8.4.6 8.4.7 8.4.8
simple-sales-tax / includes / class-sst-install.php
simple-sales-tax / includes Last commit date
abstracts 3 months ago admin 3 months ago frontend 1 month ago integrations 1 month ago v3 3 months ago vendor 6 days ago views 8 months ago class-simplesalestax.php 6 days ago class-sst-addresses.php 1 month ago class-sst-ajax.php 3 months ago class-sst-assets.php 6 months ago class-sst-blocks-integration.php 1 month ago class-sst-blocks.php 1 year ago class-sst-certificates.php 6 days ago class-sst-install.php 6 months ago class-sst-logger.php 5 months ago class-sst-marketplaces.php 6 months ago class-sst-order-controller.php 3 months ago class-sst-order.php 1 month ago class-sst-origin-address.php 8 months ago class-sst-product.php 3 months ago class-sst-rate-limit.php 5 months ago class-sst-settings.php 3 months ago class-sst-shipping.php 3 years ago class-sst-taxcloud-v3-api.php 3 months ago class-sst-taxcloud-v3.php 3 months ago class-sst-tic.php 2 years ago class-sst-updater.php 3 years ago sst-compatibility-functions.php 4 months ago sst-functions.php 6 days ago sst-message-functions.php 3 years ago sst-update-functions.php 11 months ago
class-sst-install.php
395 lines
1 <?php
2
3 if ( ! defined( 'ABSPATH' ) ) {
4 exit; // Exit if accessed directly.
5 }
6
7 /**
8 * SST Install.
9 *
10 * Handles plugin installation and upgrades.
11 *
12 * @author Simple Sales Tax
13 * @package SST
14 * @since 5.0
15 */
16 class SST_Install {
17
18 /**
19 * Callbacks that need to run for each update.
20 *
21 * @var array
22 */
23 private static $update_hooks = array(
24 '2.6' => array(
25 'sst_update_26_remove_shipping_taxable_option',
26 ),
27 '3.8' => array(
28 'sst_update_38_update_addresses',
29 ),
30 '4.2' => array(
31 'sst_update_42_migrate_settings',
32 'sst_update_42_migrate_order_data',
33 ),
34 '4.5' => array(
35 'sst_update_45_remove_license_option',
36 ),
37 '5.0' => array(
38 'sst_update_50_origin_addresses',
39 'sst_update_50_category_tics',
40 'sst_update_50_order_data',
41 ),
42 '5.9' => array(
43 'sst_update_59_tic_table',
44 ),
45 '6.0.6' => array(
46 'sst_update_606_fix_duplicate_transactions',
47 ),
48 '6.2.0' => array(
49 'sst_update_620_import_origin_addresses',
50 ),
51 '7.0.0' => array(
52 'sst_update_700_delete_package_cache',
53 'sst_update_700_delete_null_certificates',
54 'sst_update_700_migrate_certificates',
55 'sst_update_700_compress_packages',
56 ),
57 );
58
59 /**
60 * Background updater.
61 *
62 * @var SST_Updater
63 */
64 private static $background_updater;
65
66 /**
67 * Initialize installer.
68 */
69 public static function init() {
70 add_action( 'init', array( __CLASS__, 'init_background_updater' ), 5 );
71 add_action( 'admin_init', array( __CLASS__, 'check_version' ), 5 );
72 add_action( 'admin_init', array( __CLASS__, 'trigger_update' ) );
73 add_action( 'admin_init', array( __CLASS__, 'trigger_rate_removal' ) );
74 add_filter( 'plugin_action_links_' . SST_PLUGIN_BASENAME, array( __CLASS__, 'add_action_links' ) );
75 add_filter( 'woocommerce_rate_code', array( __CLASS__, 'get_rate_code' ), 10, 2 );
76 add_filter( 'woocommerce_rate_label', array( __CLASS__, 'get_rate_label' ), 10, 2 );
77 add_action( 'plugins_loaded', array( __CLASS__, 'disable_wcms_order_items_hook' ), 100 );
78 }
79
80 /**
81 * Runs on plugin deactivation. Removes all admin notices.
82 */
83 public static function deactivate() {
84 self::remove_notices();
85 self::remove_cron();
86 }
87
88 /**
89 * Initialize the background updater.
90 *
91 * @return SST_Updater
92 */
93 public static function init_background_updater() {
94 if ( ! isset( self::$background_updater ) ) {
95 require_once 'class-sst-updater.php';
96 self::$background_updater = new SST_Updater();
97 }
98
99 return self::$background_updater;
100 }
101
102 /**
103 * Compares the current version of the plugin against the version stored
104 * in the database and runs the installer if necessary.
105 */
106 public static function check_version() {
107 if (
108 is_admin()
109 && isset( $_GET['page'], $_GET['tab'], $_GET['section'] )
110 && 'wc-settings' === $_GET['page']
111 && 'integration' === $_GET['tab']
112 && 'wootax' === $_GET['section']
113 && ! defined( 'IFRAME_REQUEST' )
114 && get_option( 'wootax_version' ) !== SST()->version
115 ) {
116 self::install();
117 }
118 }
119
120 /**
121 * Remove all SST admin notices.
122 */
123 private static function remove_notices() {
124 if ( ! class_exists( 'WC_Admin_Notices' ) ) {
125 require WC()->plugin_path() . '/admin/class-wc-admin-notices.php';
126 }
127
128 WC_Admin_Notices::remove_notice( 'sst_update' );
129 }
130
131 /**
132 * Install Simple Sales Tax.
133 */
134 public static function install() {
135 // Include required classes.
136 if ( ! class_exists( 'WC_Admin_Notices' ) ) {
137 require WC()->plugin_path() . '/admin/class-wc-admin-notices.php';
138 }
139
140 // Install.
141 self::add_roles();
142 self::add_tax_rate();
143
144 // Remove existing notices, if any.
145 self::remove_notices();
146
147 // Queue updates if needed.
148 $db_version = get_option( 'wootax_version' );
149
150 if ( false !== $db_version && version_compare( $db_version, max( array_keys( self::$update_hooks ) ), '<' ) ) {
151 WC_Admin_Notices::add_custom_notice( 'sst_update', self::update_notice() );
152 } else {
153 update_option( 'wootax_version', SST()->version );
154 }
155
156 // Prompt user to remove rates if any are present.
157 if ( 'yes' !== get_option( 'wootax_keep_rates' ) && self::has_other_rates() ) {
158 $nonce = wp_create_nonce( 'sst_keep_rates' );
159 $keep_url = esc_url( admin_url( '?sst_keep_rates=yes&nonce=' . $nonce ) );
160 $delete_url = esc_url( admin_url( '?sst_keep_rates=no&nonce=' . $nonce ) );
161 $notice = sprintf(
162 /* translators: 1 - URL to keep found rates, 2 - URL to delete found rates */
163 __(
164 'TaxCloud for WooCommerce found extra rates in your tax tables. Please choose to <a href="%1$s">keep the rates</a> or <a href="%2$s">delete them</a>.',
165 'simple-sales-tax'
166 ),
167 $keep_url,
168 $delete_url
169 );
170 WC_Admin_Notices::add_custom_notice( 'sst_rates', $notice );
171 }
172
173 // Flush rewrite rules
174 flush_rewrite_rules();
175 }
176
177 /**
178 * Start update when a user clicks the "Update" button in the dashboard.
179 */
180 public static function trigger_update() {
181 if ( ! empty( $_GET['do_sst_update'] ) && wp_verify_nonce( $_GET['nonce'], 'sst_update' ) && current_user_can( 'manage_options' ) ) {
182 self::update();
183
184 // Update notice content.
185 WC_Admin_Notices::remove_notice( 'sst_update' );
186 WC_Admin_Notices::add_custom_notice( 'sst_update', self::update_notice() );
187 }
188 }
189
190 /**
191 * Remove rates when user clicks 'keep the rates' or 'delete them.'
192 */
193 public static function trigger_rate_removal() {
194 $keep_rates = ! empty( $_GET['sst_keep_rates'] ) ? sanitize_text_field( wp_unslash( $_GET['sst_keep_rates'] ) ) : ''; // phpcs:ignore WordPress.CSRF.NonceVerification
195
196 if ( ! empty( $keep_rates ) && wp_verify_nonce( $_GET['nonce'], 'sst_keep_rates' ) && current_user_can( 'manage_options' ) ) {
197 global $wpdb;
198 if ( 'no' === $keep_rates ) {
199 $wpdb->query(
200 $wpdb->prepare(
201 "DELETE FROM {$wpdb->prefix}woocommerce_tax_rates WHERE tax_rate_id != %d",
202 SST_RATE_ID
203 )
204 );
205 // Clear tax rate cache.
206 $tools_controller = new WC_REST_System_Status_Tools_Controller();
207 $tools_controller->execute_tool( 'wootax_rate_tool' );
208 } else {
209 update_option( 'wootax_keep_rates', 'yes' );
210 }
211 WC_Admin_Notices::remove_notice( 'sst_rates' );
212 }
213 }
214
215 /**
216 * Get content for update notice.
217 *
218 * @return string
219 */
220 private static function update_notice() {
221 $db_version = get_option( 'wootax_version' );
222
223 ob_start();
224
225 if ( version_compare( $db_version, max( array_keys( self::$update_hooks ) ), '<' ) ) {
226 if ( self::$background_updater->is_updating() || ! empty( $_GET['do_sst_update'] ) ) { // phpcs:ignore WordPress.CSRF.NonceVerification
227 require __DIR__ . '/admin/views/html-notice-updating.php';
228 } else {
229 require __DIR__ . '/admin/views/html-notice-update.php';
230 }
231 }
232
233 return ob_get_clean();
234 }
235
236 /**
237 * Queue all required updates to run in the background. Ripped from
238 * WooCommerce core.
239 */
240 private static function update() {
241 $current_db_version = get_option( 'wootax_version' );
242 $logger = new WC_Logger();
243 $update_queued = false;
244
245 foreach ( self::$update_hooks as $version => $update_callbacks ) {
246 if ( version_compare( $current_db_version, $version, '<' ) ) {
247 foreach ( $update_callbacks as $update_callback ) {
248 $logger->add( 'sst_db_updates', sprintf( 'Queuing %s - %s', $version, $update_callback ) );
249 self::$background_updater->push_to_queue( $update_callback );
250 $update_queued = true;
251 }
252 }
253 }
254
255 if ( $update_queued ) {
256 self::$background_updater->save()->dispatch();
257 }
258 }
259
260 /**
261 * Add custom user roles.
262 */
263 public static function add_roles() {
264 add_role(
265 'exempt-customer',
266 __( 'Exempt Customer', 'simple-sales-tax' ),
267 array(
268 'read' => true,
269 'edit_posts' => false,
270 'delete_posts' => false,
271 )
272 );
273 }
274
275 /**
276 * Add plugin action links.
277 *
278 * @param array $links Existing action links for plugin.
279 *
280 * @return array
281 */
282 public static function add_action_links( $links ) {
283 $link_text = __( 'Settings', 'simple-sales-tax' );
284 $settings_link = '<a href="admin.php?page=wc-settings&tab=integration&section=wootax">' . $link_text . '</a>';
285 array_unshift( $links, $settings_link );
286
287 return $links;
288 }
289
290 /**
291 * Add a tax rate so we can persist calculate tax totals after checkout.
292 */
293 private static function add_tax_rate() {
294 global $wpdb;
295
296 $tax_rates_table = $wpdb->prefix . 'woocommerce_tax_rates';
297
298 // Get existing rate, if any.
299 $rate_id = get_option( 'wootax_rate_id', 0 );
300
301 // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
302 $existing = $wpdb->get_row($wpdb->prepare("SELECT * FROM $tax_rates_table WHERE tax_rate_id = %d;",$rate_id));
303
304 // Add or update tax rate.
305 $_tax_rate = array(
306 'tax_rate_country' => 'WT',
307 'tax_rate_state' => 'RATE',
308 'tax_rate' => 0,
309 'tax_rate_name' => 'DO-NOT-REMOVE',
310 'tax_rate_priority' => 0,
311 'tax_rate_compound' => 1,
312 'tax_rate_shipping' => 1,
313 'tax_rate_order' => 0,
314 'tax_rate_class' => 'standard',
315 );
316
317 if ( is_null( $existing ) ) {
318 $wpdb->insert( $tax_rates_table, $_tax_rate );
319 update_option( 'wootax_rate_id', $wpdb->insert_id );
320 } else {
321 $where = array( 'tax_rate_id' => $rate_id );
322 $wpdb->update( $tax_rates_table, $_tax_rate, $where );
323 }
324 }
325
326 /**
327 * Are any extra tax rates present in the tax tables?
328 *
329 * @return bool
330 */
331 private static function has_other_rates() {
332 global $wpdb;
333 $rate_count = $wpdb->get_var(
334 $wpdb->prepare(
335 "SELECT COUNT(*) FROM {$wpdb->prefix}woocommerce_tax_rates WHERE tax_rate_id != %d",
336 SST_RATE_ID
337 )
338 );
339
340 return $rate_count > 0;
341 }
342
343 /**
344 * Return correct rate code for our tax rate (SALES-TAX).
345 *
346 * @param string $code Rate code.
347 * @param int $key Tax rate ID.
348 *
349 * @return string
350 */
351 public static function get_rate_code( $code, $key ) {
352 if ( (int) SST_RATE_ID === (int) $key ) {
353 return sst_get_rate_code();
354 } else {
355 return $code;
356 }
357 }
358
359 /**
360 * Return correct label for our tax rate ("Sales Tax").
361 *
362 * @param string $label Original label.
363 * @param int $key Tax rate id.
364 *
365 * @return string
366 */
367 public static function get_rate_label( $label, $key ) {
368 if ( (int) SST_RATE_ID === (int) $key ) {
369 return sst_get_rate_label();
370 } else {
371 return $label;
372 }
373 }
374
375 /**
376 * Disable the WC Multiple Shipping woocommerce_order_get_items hook. The
377 * hook is not needed when SST is active and leads to corruption of line
378 * item taxes.
379 */
380 public static function disable_wcms_order_items_hook() {
381 if ( sst_wcms_active() ) {
382 remove_filter( 'woocommerce_order_get_items', array( $GLOBALS['wcms']->order, 'order_item_taxes' ), 30 );
383 }
384 }
385
386 /**
387 * Remove cron job.
388 */
389 public static function remove_cron() {
390 wp_clear_scheduled_hook( 'sst_update_data_mover_settings' );
391 }
392 }
393
394 SST_Install::init();
395