2013-07-26 14:36:28 +00:00
< ? php
/**
* WooCommerce Tax Settings
*
2014-08-31 08:22:03 +00:00
* @ author WooThemes
* @ category Admin
* @ 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
if ( ! class_exists ( 'WC_Settings_Tax' ) ) :
/**
* WC_Settings_Tax
*/
class WC_Settings_Tax extends WC_Settings_Page {
2014-11-20 14:46:19 +00:00
protected $id = 'tax' ;
2013-07-26 14:36:28 +00:00
/**
* Constructor .
*/
public function __construct () {
$this -> label = __ ( 'Tax' , 'woocommerce' );
2014-11-20 14:46:19 +00:00
parent :: __construct ();
2013-07-26 14:36:28 +00:00
}
/**
* Get sections
*
* @ return array
*/
public function get_sections () {
$sections = array (
'' => __ ( 'Tax Options' , 'woocommerce' ),
'standard' => __ ( 'Standard Rates' , 'woocommerce' )
);
// Get tax classes and display as links
2014-11-20 14:46:19 +00:00
$tax_classes = $this -> get_tax_classes ();
2013-07-26 14:36:28 +00:00
2014-11-20 14:46:19 +00:00
foreach ( $tax_classes as $class ) {
$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
}
/**
* Get settings array
*
* @ return array
*/
public function get_settings () {
2014-11-20 14:46:19 +00:00
$tax_classes = $this -> get_tax_classes ();
2013-07-26 14:36:28 +00:00
$classes_options = array ();
2014-11-20 14:46:19 +00:00
foreach ( $tax_classes as $class ) {
$classes_options [ sanitize_title ( $class ) ] = esc_html ( $class );
}
2014-09-12 11:20:06 +00:00
2014-11-20 14:46:19 +00:00
return apply_filters ( 'woocommerce_get_settings_' . $this -> id , include ( 'settings-tax.php' ) );
2013-07-26 14:36:28 +00:00
}
/**
* Output the settings
*/
public function output () {
global $current_section ;
2014-11-20 14:46:19 +00:00
$tax_classes = $this -> get_tax_classes ();
2013-07-26 14:36:28 +00:00
if ( $current_section == 'standard' || in_array ( $current_section , array_map ( 'sanitize_title' , $tax_classes ) ) ) {
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 );
}
}
/**
* Save settings
*/
public function save () {
2014-01-20 16:00:15 +00:00
global $current_section , $wpdb ;
2013-07-26 14:36:28 +00:00
if ( ! $current_section ) {
$settings = $this -> get_settings ();
WC_Admin_Settings :: save_fields ( $settings );
} else {
$this -> save_tax_rates ();
}
2014-01-20 16:00:15 +00:00
$wpdb -> query ( " DELETE FROM ` $wpdb->options ` WHERE `option_name` LIKE ('_transient_wc_tax_rates_%') OR `option_name` LIKE ('_transient_timeout_wc_tax_rates_%') " );
2013-07-26 14:36:28 +00:00
}
/**
* Output tax rate tables
*/
public function output_tax_rates () {
2014-11-20 00:51:01 +00:00
global $wpdb ;
2013-07-26 14:36:28 +00:00
2013-08-13 11:18:20 +00:00
$page = ! empty ( $_GET [ 'p' ] ) ? absint ( $_GET [ 'p' ] ) : 1 ;
$limit = 100 ;
2014-11-20 00:51:01 +00:00
$current_class = $this -> get_current_tax_class ();
2013-07-26 14:36:28 +00:00
2014-11-20 14:46:19 +00:00
include ( 'html-settings-tax.php' );
}
2013-07-26 14:36:28 +00:00
2014-11-20 14:46:19 +00:00
/**
* Get tax classes
* @ return array
*/
private function get_tax_classes () {
return array_filter ( array_map ( 'trim' , explode ( " \n " , get_option ( 'woocommerce_tax_classes' ) ) ) );
2013-07-26 14:36:28 +00:00
}
/**
2014-11-20 00:51:01 +00:00
* Get tax class being edited
* @ return string
2013-07-26 14:36:28 +00:00
*/
2014-11-20 00:51:01 +00:00
private function get_current_tax_class () {
global $current_section ;
2013-07-26 14:36:28 +00:00
2014-11-20 14:46:19 +00:00
$tax_classes = $this -> get_tax_classes ();
2013-07-26 14:36:28 +00:00
$current_class = '' ;
2014-08-31 08:22:03 +00:00
foreach ( $tax_classes as $class ) {
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 11:11:04 +00:00
/**
* Insert a tax rate
* @ param array $_tax_rate
* @ return int tax rate id
*/
private function insert_tax_rate ( $_tax_rate ) {
global $wpdb ;
$wpdb -> insert ( $wpdb -> prefix . 'woocommerce_tax_rates' , $_tax_rate );
$tax_rate_id = $wpdb -> insert_id ;
do_action ( 'woocommerce_tax_rate_added' , $tax_rate_id , $_tax_rate );
return $tax_rate_id ;
}
/**
* Update a tax rate
* @ param int $tax_rate_id
* @ param array $_tax_rate
* @ return int tax rate id
*/
private function update_tax_rate ( $tax_rate_id , $_tax_rate ) {
global $wpdb ;
$tax_rate_id = absint ( $tax_rate_id );
$wpdb -> update (
$wpdb -> prefix . " woocommerce_tax_rates " ,
$_tax_rate ,
array (
'tax_rate_id' => $tax_rate_id
)
);
do_action ( 'woocommerce_tax_rate_updated' , $tax_rate_id , $_tax_rate );
return $tax_rate_id ;
}
2014-11-20 00:51:01 +00:00
/**
* Delete a tax rate from the database
* @ param int $tax_rate_id
*/
private function delete_tax_rate ( $tax_rate_id ) {
global $wpdb ;
2013-07-26 14:36:28 +00:00
2014-11-20 00:51:01 +00:00
$wpdb -> query ( $wpdb -> prepare ( " DELETE FROM { $wpdb -> prefix } woocommerce_tax_rate_locations WHERE tax_rate_id = %d; " , $tax_rate_id ) );
$wpdb -> query ( $wpdb -> prepare ( " DELETE FROM { $wpdb -> prefix } woocommerce_tax_rates WHERE tax_rate_id = %d; " , $tax_rate_id ) );
2013-07-26 14:36:28 +00:00
2014-11-20 00:51:01 +00:00
do_action ( 'woocommerce_tax_rate_deleted' , $tax_rate_id );
}
2013-07-26 14:36:28 +00:00
2014-11-20 00:51:01 +00:00
/**
* format the state
* @ param string $state
* @ return string
*/
2014-11-20 15:43:40 +00:00
private function format_tax_rate_state ( $state ) {
2014-11-20 00:51:01 +00:00
$state = strtoupper ( $state );
return $state === '*' ? '' : $state ;
}
2013-07-26 14:36:28 +00:00
2014-11-20 00:51:01 +00:00
/**
* format the country
* @ param string $state
* @ return string
*/
2014-11-20 15:43:40 +00:00
private function format_tax_rate_country ( $country ) {
2014-11-20 00:51:01 +00:00
$country = strtoupper ( $country );
return $country === '*' ? '' : $country ;
}
2013-07-26 14:36:28 +00:00
2014-11-20 00:51:01 +00:00
/**
* format the tax rate name
* @ param string $state
* @ return string
*/
2014-11-20 15:43:40 +00:00
private function format_tax_rate_name ( $name ) {
2014-11-20 00:51:01 +00:00
return $name ? $name : __ ( 'Tax' , 'woocommerce' );
}
2013-07-26 14:36:28 +00:00
2014-11-20 00:51:01 +00:00
/**
* format the rate
* @ param string $state
* @ return float
*/
private function format_tax_rate ( $rate ) {
return number_format ( ( double ) $rate , 4 , '.' , '' );
}
2014-08-31 08:22:03 +00:00
2014-11-20 00:51:01 +00:00
/**
* format the city
* @ param string $state
* @ return string
*/
private function format_tax_rate_city ( $city ) {
return strtoupper ( $city );
}
2014-08-31 08:22:03 +00:00
2014-11-20 00:51:01 +00:00
/**
* format the postcodes
* @ param string $state
* @ return string
*/
private function format_tax_rate_postcode ( $postcode ) {
return strtoupper ( $postcode );
}
2013-07-26 14:36:28 +00:00
2014-11-20 15:43:40 +00:00
/**
* format the priority
* @ param string $priority
* @ return int
*/
private function format_tax_rate_priority ( $priority ) {
return absint ( $priority );
}
2014-11-20 00:51:01 +00:00
/**
* Update postcodes for a tax rate in the DB
* @ param int $tax_rate_id
* @ param string $postcodes
* @ return string
*/
private function update_tax_rate_postcodes ( $tax_rate_id , $postcodes ) {
global $wpdb ;
2013-07-26 14:36:28 +00:00
2014-11-20 00:51:01 +00:00
// Delete old
$wpdb -> query ( $wpdb -> prepare ( " DELETE FROM { $wpdb -> prefix } woocommerce_tax_rate_locations WHERE tax_rate_id = %d AND location_type = 'postcode'; " , $tax_rate_id ) );
2013-07-26 14:36:28 +00:00
2014-11-20 00:51:01 +00:00
// Add changed
$postcodes = array_filter ( explode ( ';' , $postcodes ) );
$postcode_query = array ();
2013-07-26 14:36:28 +00:00
2014-11-20 00:51:01 +00:00
foreach ( $postcodes as $postcode ) {
if ( strstr ( $postcode , '-' ) ) {
$postcode_parts = explode ( '-' , $postcode );
2014-05-19 05:49:35 +00:00
2014-11-20 00:51:01 +00:00
if ( is_numeric ( $postcode_parts [ 0 ] ) && is_numeric ( $postcode_parts [ 1 ] ) && $postcode_parts [ 1 ] > $postcode_parts [ 0 ] ) {
for ( $i = $postcode_parts [ 0 ]; $i <= $postcode_parts [ 1 ]; $i ++ ) {
if ( ! $i ) {
continue ;
}
2014-05-19 05:49:35 +00:00
2014-11-20 00:51:01 +00:00
if ( strlen ( $i ) < strlen ( $postcode_parts [ 0 ] ) ) {
$i = str_pad ( $i , strlen ( $postcode_parts [ 0 ] ), " 0 " , STR_PAD_LEFT );
}
2013-07-26 14:36:28 +00:00
2014-11-20 00:51:01 +00:00
$postcode_query [] = " ( ' " . esc_sql ( $i ) . " ', $tax_rate_id , 'postcode' ) " ;
}
2014-08-31 08:22:03 +00:00
}
2014-11-20 00:51:01 +00:00
} elseif ( $postcode ) {
$postcode_query [] = " ( ' " . esc_sql ( $postcode ) . " ', $tax_rate_id , 'postcode' ) " ;
}
}
2013-07-26 14:36:28 +00:00
2014-11-20 00:51:01 +00:00
if ( ! empty ( $postcode_query ) ) {
$wpdb -> query ( " INSERT INTO { $wpdb -> prefix } woocommerce_tax_rate_locations ( location_code, tax_rate_id, location_type ) VALUES " . implode ( ',' , $postcode_query ) );
}
}
2013-07-26 14:36:28 +00:00
2014-11-20 00:51:01 +00:00
/**
* Update cities for a tax rate in the DB
* @ param int $tax_rate_id
* @ param string $cities
* @ return string
*/
private function update_tax_rate_cities ( $tax_rate_id , $cities ) {
global $wpdb ;
2013-07-26 14:36:28 +00:00
2014-11-20 00:51:01 +00:00
// Delete old
$wpdb -> query ( $wpdb -> prepare ( " DELETE FROM { $wpdb -> prefix } woocommerce_tax_rate_locations WHERE tax_rate_id = %d AND location_type = 'city'; " , $tax_rate_id ) );
2014-05-19 05:49:35 +00:00
2014-11-20 00:51:01 +00:00
// Add changed
$cities = array_filter ( explode ( ';' , $cities ) );
$city_query = array ();
2013-07-26 14:36:28 +00:00
2014-11-20 00:51:01 +00:00
foreach ( $cities as $city ) {
$city_query [] = " ( ' " . esc_sql ( $city ) . " ', $tax_rate_id , 'city' ) " ;
}
2014-05-20 23:14:49 +00:00
2014-11-20 00:51:01 +00:00
if ( ! empty ( $city_query ) ) {
$wpdb -> query ( " INSERT INTO { $wpdb -> prefix } woocommerce_tax_rate_locations ( location_code, tax_rate_id, location_type ) VALUES " . implode ( ',' , $city_query ) );
}
}
2013-07-26 14:36:28 +00:00
2014-11-20 00:51:01 +00:00
/**
2014-11-20 11:11:04 +00:00
* Get a posted tax rate
* @ 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
* @ 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 ) {
$_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' ,
'tax_rate_priority'
);
2013-07-26 14:36:28 +00:00
2014-11-20 11:11:04 +00:00
foreach ( $tax_rate_keys as $tax_rate_key ) {
if ( isset ( $_POST [ $tax_rate_key ] ) && isset ( $_POST [ $tax_rate_key ][ $key ] ) ) {
$_tax_rate [ $tax_rate_key ] = wc_clean ( $_POST [ $tax_rate_key ][ $key ] );
2014-11-20 15:43:40 +00:00
$_tax_rate [ $tax_rate_key ] = call_user_func ( array ( $this , 'format_' . $tax_rate_key ), $_tax_rate [ $tax_rate_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 11:11:04 +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 ;
2013-07-26 14:36:28 +00:00
2014-11-20 11:11:04 +00:00
return $_tax_rate ;
}
2013-07-26 14:36:28 +00:00
2014-11-20 11:11:04 +00:00
/**
* Save tax rates
*/
public function save_tax_rates () {
if ( empty ( $_POST [ 'tax_rate_country' ] ) ) {
return ;
}
2014-11-20 00:51:01 +00:00
2014-11-20 11:11:04 +00:00
$current_class = sanitize_title ( $this -> get_current_tax_class () );
$index = 0 ;
2014-11-20 00:51:01 +00:00
2014-11-20 11:11:04 +00:00
// Loop posted fields
foreach ( $_POST [ 'tax_rate_country' ] as $key => $value ) {
$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 ) {
$tax_rate_id = $this -> insert_tax_rate ( $_tax_rate );
} else {
// Remove rates
2014-11-20 00:51:01 +00:00
if ( 1 == $_POST [ 'remove_tax_rate' ][ $key ] ) {
2014-11-20 15:43:40 +00:00
$this -> delete_tax_rate ( $key );
2014-11-20 00:51:01 +00:00
continue ;
2013-07-26 14:36:28 +00:00
}
2014-11-20 11:11:04 +00:00
$tax_rate_id = $this -> update_tax_rate ( $key , $_tax_rate );
2014-11-20 00:51:01 +00:00
}
if ( isset ( $_POST [ 'tax_rate_postcode' ][ $key ] ) ) {
$this -> update_tax_rate_postcodes ( $tax_rate_id , $this -> format_tax_rate_postcode ( $_POST [ 'tax_rate_postcode' ][ $key ] ) );
}
if ( isset ( $_POST [ 'tax_rate_city' ][ $key ] ) ) {
$this -> update_tax_rate_cities ( $tax_rate_id , $this -> format_tax_rate_city ( $_POST [ 'tax_rate_city' ][ $key ] ) );
2013-07-26 14:36:28 +00:00
}
}
}
}
endif ;
2014-05-19 05:49:35 +00:00
return new WC_Settings_Tax ();