woocommerce/includes/admin/settings/class-wc-settings-tax.php

403 lines
9.9 KiB
PHP
Raw Normal View History

2013-07-26 14:36:28 +00:00
<?php
/**
* WooCommerce Tax Settings
*
* @author WooThemes
* @category Admin
* @package WooCommerce/Admin
2013-07-26 14:36:28 +00:00
* @version 2.1.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
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 {
protected $id = 'tax';
2013-07-26 14:36:28 +00:00
/**
* Constructor.
*/
public function __construct() {
$this->label = __( 'Tax', 'woocommerce' );
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
$tax_classes = $this->get_tax_classes();
2013-07-26 14:36:28 +00:00
foreach ( $tax_classes as $class ) {
$sections[ sanitize_title( $class ) ] = sprintf( __( '%s Rates', 'woocommerce' ), $class );
}
2013-07-26 14:36:28 +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() {
$tax_classes = $this->get_tax_classes();
2013-07-26 14:36:28 +00:00
$classes_options = array();
foreach ( $tax_classes as $class ) {
$classes_options[ sanitize_title( $class ) ] = esc_html( $class );
}
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;
$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 ) ) ) {
$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() {
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();
}
$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
include( 'html-settings-tax.php' );
}
2013-07-26 14:36:28 +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
$tax_classes = $this->get_tax_classes();
2013-07-26 14:36:28 +00:00
$current_class = '';
foreach( $tax_classes as $class ) {
if ( sanitize_title( $class ) == $current_section ) {
2013-07-26 14:36:28 +00:00
$current_class = $class;
}
}
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-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-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-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-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-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-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-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;
return new WC_Settings_Tax();