2013-07-26 14:36:28 +00:00
< ? php
/**
2015-11-03 13:53:50 +00:00
* WooCommerce Tax Settings
2013-07-26 14:36:28 +00:00
*
2020-08-05 16:36:24 +00:00
* @ package WooCommerce\Admin
2013-07-26 14:36:28 +00:00
* @ version 2.1 . 0
*/
2014-09-20 19:55:47 +00:00
if ( ! defined ( 'ABSPATH' ) ) {
2014-11-20 14:46:19 +00:00
exit ;
2014-09-20 19:55:47 +00:00
}
2013-07-26 14:36:28 +00:00
2017-10-12 10:26:55 +00:00
if ( class_exists ( 'WC_Settings_Tax' , false ) ) {
return new WC_Settings_Tax ();
}
2013-07-26 14:36:28 +00:00
/**
2015-11-03 13:31:20 +00:00
* WC_Settings_Tax .
2013-07-26 14:36:28 +00:00
*/
class WC_Settings_Tax extends WC_Settings_Page {
/**
* Constructor .
*/
public function __construct () {
2017-10-12 10:26:55 +00:00
$this -> id = 'tax' ;
2013-07-26 14:36:28 +00:00
$this -> label = __ ( 'Tax' , 'woocommerce' );
2017-08-12 00:36:35 +00:00
2017-10-25 11:51:19 +00:00
add_filter ( 'woocommerce_settings_tabs_array' , array ( $this , 'add_settings_page' ), 20 );
if ( wc_tax_enabled () ) {
add_action ( 'woocommerce_sections_' . $this -> id , array ( $this , 'output_sections' ) );
add_action ( 'woocommerce_settings_' . $this -> id , array ( $this , 'output' ) );
add_action ( 'woocommerce_settings_save_' . $this -> id , array ( $this , 'save' ) );
}
2013-07-26 14:36:28 +00:00
}
2016-01-05 11:23:15 +00:00
/**
* Add this page to settings .
2017-05-15 11:50:52 +00:00
*
2017-10-12 10:26:55 +00:00
* @ param array $pages Existing pages .
2017-05-15 11:50:52 +00:00
* @ return array | mixed
2016-01-05 11:23:15 +00:00
*/
public function add_settings_page ( $pages ) {
if ( wc_tax_enabled () ) {
return parent :: add_settings_page ( $pages );
} else {
return $pages ;
}
}
2013-07-26 14:36:28 +00:00
/**
2015-11-03 13:31:20 +00:00
* Get sections .
2013-07-26 14:36:28 +00:00
*
* @ return array
*/
public function get_sections () {
$sections = array (
2016-10-12 10:16:30 +00:00
'' => __ ( 'Tax options' , 'woocommerce' ),
'standard' => __ ( 'Standard rates' , 'woocommerce' ),
2013-07-26 14:36:28 +00:00
);
2017-10-12 10:26:55 +00:00
// Get tax classes and display as links.
2014-11-21 13:06:30 +00:00
$tax_classes = WC_Tax :: get_tax_classes ();
2013-07-26 14:36:28 +00:00
2014-11-20 14:46:19 +00:00
foreach ( $tax_classes as $class ) {
2021-03-30 09:08:35 +00:00
/* translators: $s tax rate section name */
2016-10-12 10:16:30 +00:00
$sections [ sanitize_title ( $class ) ] = sprintf ( __ ( '%s rates' , 'woocommerce' ), $class );
2014-08-31 08:22:03 +00:00
}
2013-07-26 14:36:28 +00:00
2014-02-17 14:30:37 +00:00
return apply_filters ( 'woocommerce_get_sections_' . $this -> id , $sections );
2013-07-26 14:36:28 +00:00
}
/**
2015-11-03 13:31:20 +00:00
* Get settings array .
2013-07-26 14:36:28 +00:00
*
2017-10-12 10:26:55 +00:00
* @ param string $current_section Current section being shown .
2013-07-26 14:36:28 +00:00
* @ return array
*/
2017-06-27 13:58:33 +00:00
public function get_settings ( $current_section = '' ) {
$settings = array ();
if ( '' === $current_section ) {
2020-09-17 16:12:57 +00:00
$settings = include __DIR__ . '/views/settings-tax.php' ;
2017-10-12 10:26:55 +00:00
}
2017-06-27 13:58:33 +00:00
return apply_filters ( 'woocommerce_get_settings_' . $this -> id , $settings , $current_section );
2013-07-26 14:36:28 +00:00
}
/**
2015-11-03 13:31:20 +00:00
* Output the settings .
2013-07-26 14:36:28 +00:00
*/
public function output () {
global $current_section ;
2017-01-25 21:38:13 +00:00
$tax_classes = WC_Tax :: get_tax_class_slugs ();
2013-07-26 14:36:28 +00:00
2021-03-30 09:08:35 +00:00
if ( 'standard' === $current_section || in_array ( $current_section , array_filter ( $tax_classes ), true ) ) {
2014-08-31 08:22:03 +00:00
$this -> output_tax_rates ();
} else {
2013-07-26 14:36:28 +00:00
$settings = $this -> get_settings ();
WC_Admin_Settings :: output_fields ( $settings );
}
}
/**
2015-11-03 13:31:20 +00:00
* Save settings .
2013-07-26 14:36:28 +00:00
*/
public function save () {
2019-12-13 19:58:14 +00:00
// phpcs:disable WordPress.Security.NonceVerification.Missing
2017-05-24 14:21:20 +00:00
global $current_section ;
2013-07-26 14:36:28 +00:00
if ( ! $current_section ) {
$settings = $this -> get_settings ();
WC_Admin_Settings :: save_fields ( $settings );
2019-03-20 15:27:07 +00:00
if ( isset ( $_POST [ 'woocommerce_tax_classes' ] ) ) {
$this -> save_tax_classes ( wp_unslash ( $_POST [ 'woocommerce_tax_classes' ] ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
}
2014-11-20 15:46:07 +00:00
} elseif ( ! empty ( $_POST [ 'tax_rate_country' ] ) ) {
2013-07-26 14:36:28 +00:00
$this -> save_tax_rates ();
}
2014-01-20 16:00:15 +00:00
2018-01-26 09:22:09 +00:00
if ( $current_section ) {
do_action ( 'woocommerce_update_options_' . $this -> id . '_' . $current_section );
}
2018-01-18 17:47:26 +00:00
// Invalidate caches.
2019-11-28 13:03:57 +00:00
WC_Cache_Helper :: invalidate_cache_group ( 'taxes' );
2018-01-18 17:47:26 +00:00
WC_Cache_Helper :: get_transient_version ( 'shipping' , true );
2019-12-13 19:58:14 +00:00
// phpcs:enable WordPress.Security.NonceVerification.Missing
2019-03-20 15:27:07 +00:00
}
/**
* Saves tax classes defined in the textarea to the tax class table instead of an option .
*
* @ param string $raw_tax_classes Posted value .
* @ return null
*/
public function save_tax_classes ( $raw_tax_classes ) {
2019-07-09 18:23:46 +00:00
$tax_classes = array_filter ( array_map ( 'trim' , explode ( " \n " , $raw_tax_classes ) ) );
2019-03-20 15:27:07 +00:00
$existing_tax_classes = WC_Tax :: get_tax_classes ();
$removed = array_diff ( $existing_tax_classes , $tax_classes );
$added = array_diff ( $tax_classes , $existing_tax_classes );
foreach ( $removed as $name ) {
WC_Tax :: delete_tax_class_by ( 'name' , $name );
}
foreach ( $added as $name ) {
2021-03-30 09:08:35 +00:00
$tax_class = WC_Tax :: create_tax_class ( $name );
// Display any error that could be triggered while creating tax classes.
if ( is_wp_error ( $tax_class ) ) {
WC_Admin_Settings :: add_error (
sprintf (
/* translators: 1: tax class name 2: error message */
esc_html__ ( 'Additional tax class "%1$s" couldn\'t be saved. %2$s.' , 'woocommerce' ),
esc_html ( $name ),
$tax_class -> get_error_message ()
)
);
}
2019-03-20 15:27:07 +00:00
}
return null ;
2013-07-26 14:36:28 +00:00
}
2015-08-13 20:57:54 +00:00
/**
2015-11-03 13:31:20 +00:00
* Output tax rate tables .
2015-08-13 20:57:54 +00:00
*/
public function output_tax_rates () {
2017-05-15 09:54:06 +00:00
global $current_section ;
2015-08-13 20:57:54 +00:00
$current_class = $this -> get_current_tax_class ();
2015-08-07 21:28:44 +00:00
$countries = array ();
foreach ( WC () -> countries -> get_allowed_countries () as $value => $label ) {
$countries [] = array (
'value' => $value ,
2016-01-23 16:32:09 +00:00
'label' => esc_js ( html_entity_decode ( $label ) ),
2015-08-07 21:28:44 +00:00
);
}
$states = array ();
foreach ( WC () -> countries -> get_allowed_country_states () as $label ) {
foreach ( $label as $code => $state ) {
$states [] = array (
'value' => $code ,
2016-01-23 16:32:09 +00:00
'label' => esc_js ( html_entity_decode ( $state ) ),
2015-08-07 21:28:44 +00:00
);
}
}
2018-03-05 18:59:17 +00:00
$base_url = admin_url (
add_query_arg (
array (
'page' => 'wc-settings' ,
'tab' => 'tax' ,
'section' => $current_section ,
2019-12-13 20:51:14 +00:00
),
'admin.php'
2018-03-05 18:59:17 +00:00
)
);
2015-08-12 18:18:49 +00:00
2015-08-07 21:28:44 +00:00
// Localize and enqueue our js.
2018-03-05 18:59:17 +00:00
wp_localize_script (
2019-12-13 20:51:14 +00:00
'wc-settings-tax' ,
'htmlSettingsTaxLocalizeScript' ,
array (
2018-03-05 18:59:17 +00:00
'current_class' => $current_class ,
'wc_tax_nonce' => wp_create_nonce ( 'wc_tax_nonce-class:' . $current_class ),
'base_url' => $base_url ,
'rates' => array_values ( WC_Tax :: get_rates_for_tax_class ( $current_class ) ),
2021-03-30 09:08:35 +00:00
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
2018-03-05 18:59:17 +00:00
'page' => ! empty ( $_GET [ 'p' ] ) ? absint ( $_GET [ 'p' ] ) : 1 ,
'limit' => 100 ,
'countries' => $countries ,
'states' => $states ,
'default_rate' => array (
'tax_rate_id' => 0 ,
'tax_rate_country' => '' ,
'tax_rate_state' => '' ,
'tax_rate' => '' ,
'tax_rate_name' => '' ,
'tax_rate_priority' => 1 ,
'tax_rate_compound' => 0 ,
'tax_rate_shipping' => 1 ,
'tax_rate_order' => null ,
'tax_rate_class' => $current_class ,
),
'strings' => array (
'no_rows_selected' => __ ( 'No row(s) selected' , 'woocommerce' ),
'unload_confirmation_msg' => __ ( 'Your changed data will be lost if you leave this page without saving.' , 'woocommerce' ),
'csv_data_cols' => array (
__ ( 'Country code' , 'woocommerce' ),
__ ( 'State code' , 'woocommerce' ),
__ ( 'Postcode / ZIP' , 'woocommerce' ),
__ ( 'City' , 'woocommerce' ),
__ ( 'Rate %' , 'woocommerce' ),
__ ( 'Tax name' , 'woocommerce' ),
__ ( 'Priority' , 'woocommerce' ),
__ ( 'Compound' , 'woocommerce' ),
__ ( 'Shipping' , 'woocommerce' ),
__ ( 'Tax class' , 'woocommerce' ),
),
2015-08-07 21:28:44 +00:00
),
2018-03-05 18:59:17 +00:00
)
);
2015-08-07 21:28:44 +00:00
wp_enqueue_script ( 'wc-settings-tax' );
2020-08-26 19:58:22 +00:00
include __DIR__ . '/views/html-settings-tax.php' ;
2014-11-20 14:46:19 +00:00
}
2013-07-26 14:36:28 +00:00
/**
2015-11-03 13:31:20 +00:00
* Get tax class being edited .
2017-10-12 10:26:55 +00:00
*
2014-11-20 00:51:01 +00:00
* @ return string
2013-07-26 14:36:28 +00:00
*/
2015-08-13 20:57:54 +00:00
private static function get_current_tax_class () {
2014-11-20 00:51:01 +00:00
global $current_section ;
2013-07-26 14:36:28 +00:00
2014-11-21 13:06:30 +00:00
$tax_classes = WC_Tax :: get_tax_classes ();
2013-07-26 14:36:28 +00:00
$current_class = '' ;
2016-08-27 04:23:02 +00:00
foreach ( $tax_classes as $class ) {
2017-10-12 10:26:55 +00:00
if ( sanitize_title ( $class ) === $current_section ) {
2013-07-26 14:36:28 +00:00
$current_class = $class ;
2014-08-31 08:22:03 +00:00
}
}
2013-07-26 14:36:28 +00:00
2014-11-20 00:51:01 +00:00
return $current_class ;
}
2013-07-26 14:36:28 +00:00
2014-11-20 00:51:01 +00:00
/**
2015-11-03 13:31:20 +00:00
* Get a posted tax rate .
2017-10-12 10:26:55 +00:00
*
* @ param string $key Key of tax rate in the post data array .
* @ param int $order Position / order of rate .
* @ param string $class Tax class for rate .
2014-11-20 11:11:04 +00:00
* @ return array
2014-11-20 00:51:01 +00:00
*/
2014-11-20 11:11:04 +00:00
private function get_posted_tax_rate ( $key , $order , $class ) {
2018-03-05 18:59:17 +00:00
$tax_rate = array ();
2014-11-20 00:51:01 +00:00
$tax_rate_keys = array (
'tax_rate_country' ,
'tax_rate_state' ,
'tax_rate' ,
'tax_rate_name' ,
2016-08-27 01:46:45 +00:00
'tax_rate_priority' ,
2014-11-20 00:51:01 +00:00
);
2013-07-26 14:36:28 +00:00
2021-03-30 09:08:35 +00:00
// phpcs:disable WordPress.Security.NonceVerification.Missing
2014-11-20 11:11:04 +00:00
foreach ( $tax_rate_keys as $tax_rate_key ) {
2017-10-12 10:26:55 +00:00
if ( isset ( $_POST [ $tax_rate_key ], $_POST [ $tax_rate_key ][ $key ] ) ) {
$tax_rate [ $tax_rate_key ] = wc_clean ( wp_unslash ( $_POST [ $tax_rate_key ][ $key ] ) );
2014-11-20 00:51:01 +00:00
}
2014-11-20 11:11:04 +00:00
}
2013-07-26 14:36:28 +00:00
2014-11-20 18:41:51 +00:00
$tax_rate [ 'tax_rate_compound' ] = isset ( $_POST [ 'tax_rate_compound' ][ $key ] ) ? 1 : 0 ;
$tax_rate [ 'tax_rate_shipping' ] = isset ( $_POST [ 'tax_rate_shipping' ][ $key ] ) ? 1 : 0 ;
$tax_rate [ 'tax_rate_order' ] = $order ;
$tax_rate [ 'tax_rate_class' ] = $class ;
2021-03-30 09:08:35 +00:00
// phpcs:enable WordPress.Security.NonceVerification.Missing
2013-07-26 14:36:28 +00:00
2014-11-20 18:41:51 +00:00
return $tax_rate ;
2014-11-20 11:11:04 +00:00
}
2013-07-26 14:36:28 +00:00
2014-11-20 11:11:04 +00:00
/**
2015-11-03 13:31:20 +00:00
* Save tax rates .
2014-11-20 11:11:04 +00:00
*/
public function save_tax_rates () {
2015-02-19 06:52:34 +00:00
global $wpdb ;
2021-03-30 09:08:35 +00:00
$current_class = sanitize_title ( $this -> get_current_tax_class () );
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.NonceVerification.Missing
2017-10-12 10:26:55 +00:00
$posted_countries = wc_clean ( wp_unslash ( $_POST [ 'tax_rate_country' ] ) );
2015-02-19 06:52:34 +00:00
2017-10-12 10:26:55 +00:00
// get the tax rate id of the first submited row.
$first_tax_rate_id = key ( $posted_countries );
2015-02-19 06:52:34 +00:00
2017-10-12 10:26:55 +00:00
// get the order position of the first tax rate id.
2015-02-19 06:52:34 +00:00
$tax_rate_order = absint ( $wpdb -> get_var ( $wpdb -> prepare ( " SELECT tax_rate_order FROM { $wpdb -> prefix } woocommerce_tax_rates WHERE tax_rate_id = %s " , $first_tax_rate_id ) ) );
2015-03-13 12:44:04 +00:00
2015-02-19 06:52:34 +00:00
$index = isset ( $tax_rate_order ) ? $tax_rate_order : 0 ;
2014-11-20 00:51:01 +00:00
2017-10-12 10:26:55 +00:00
// Loop posted fields.
2021-03-30 09:08:35 +00:00
// phpcs:disable WordPress.Security.NonceVerification.Missing
2017-10-12 10:26:55 +00:00
foreach ( $posted_countries as $key => $value ) {
2018-03-05 18:59:17 +00:00
$mode = ( 0 === strpos ( $key , 'new-' ) ) ? 'insert' : 'update' ;
$tax_rate = $this -> get_posted_tax_rate ( $key , $index ++ , $current_class );
2014-11-20 00:51:01 +00:00
2014-11-20 11:11:04 +00:00
if ( 'insert' === $mode ) {
2014-11-20 18:41:51 +00:00
$tax_rate_id = WC_Tax :: _insert_tax_rate ( $tax_rate );
2021-03-30 09:08:35 +00:00
} elseif ( isset ( $_POST [ 'remove_tax_rate' ][ $key ] ) && 1 === absint ( $_POST [ 'remove_tax_rate' ][ $key ] ) ) {
2015-03-13 12:44:04 +00:00
$tax_rate_id = absint ( $key );
WC_Tax :: _delete_tax_rate ( $tax_rate_id );
2014-11-20 15:46:07 +00:00
continue ;
2014-11-20 11:11:04 +00:00
} else {
2015-03-13 12:44:04 +00:00
$tax_rate_id = absint ( $key );
2014-11-20 18:41:51 +00:00
WC_Tax :: _update_tax_rate ( $tax_rate_id , $tax_rate );
2014-11-20 00:51:01 +00:00
}
if ( isset ( $_POST [ 'tax_rate_postcode' ][ $key ] ) ) {
2017-10-12 10:26:55 +00:00
WC_Tax :: _update_tax_rate_postcodes ( $tax_rate_id , wc_clean ( wp_unslash ( $_POST [ 'tax_rate_postcode' ][ $key ] ) ) );
2014-11-20 00:51:01 +00:00
}
if ( isset ( $_POST [ 'tax_rate_city' ][ $key ] ) ) {
2017-10-12 10:26:55 +00:00
WC_Tax :: _update_tax_rate_cities ( $tax_rate_id , wc_clean ( wp_unslash ( $_POST [ 'tax_rate_city' ][ $key ] ) ) );
2013-07-26 14:36:28 +00:00
}
}
2021-03-30 09:08:35 +00:00
// phpcs:enable WordPress.Security.NonceVerification.Missing
2013-07-26 14:36:28 +00:00
}
}
2014-05-19 05:49:35 +00:00
return new WC_Settings_Tax ();