Zones first draft with backbone saving of zone names

This commit is contained in:
Mike Jolley 2015-12-10 11:55:03 +00:00
parent 56f274b68b
commit 14eeb9f936
13 changed files with 689 additions and 55 deletions

File diff suppressed because one or more lines are too long

View File

@ -2117,8 +2117,16 @@ table.wc_shipping_zones {
line-height: 30px; line-height: 30px;
padding: 1em 1em; padding: 1em 1em;
font-size: 14px; font-size: 14px;
background: #fff;
} }
tbody tr:nth-child(odd) { tbody.wc-shipping-zone-rows {
tr:nth-child(odd) {
td {
background: #f9f9f9;
}
}
}
tr.odd {
td { td {
background: #f9f9f9; background: #f9f9f9;
} }
@ -2173,8 +2181,30 @@ table.wc_shipping_zones {
width: 100%; width: 100%;
} }
} }
a.delete { .wc-shipping-zone-actions {
width: 3em;
a.wc-shipping-zone-edit {
@include ir(); @include ir();
float: right;
&:before {
@include icon;
content: "\e603";
color: #999;
line-height: 30px;
}
&:hover {
&:before {
color: $red;
}
}
}
a.wc-shipping-zone-delete {
@include ir();
float: right;
margin-left: 1em;
&:before { &:before {
@include icon; @include icon;
@ -2189,6 +2219,7 @@ table.wc_shipping_zones {
} }
} }
} }
}
tfoot { tfoot {
input { input {
float:right; float:right;

View File

@ -0,0 +1,248 @@
/* global shippingZonesLocalizeScript, ajaxurl */
( function( $, data, wp, ajaxurl ) {
$( function() {
var $table = $( '.wc_shipping_zones' ),
$tbody = $( '.wc-shipping-zone-rows' ),
$save_button = $( 'input[name="save"]' ),
// Backbone model
ShippingZone = Backbone.Model.extend({
changes: {},
logChanges: function( changedRows ) {
var changes = this.changes || {};
_.each( changedRows, function( row, id ) {
changes[ id ] = _.extend( changes[ id ] || { zone_id : id }, row );
} );
this.changes = changes;
this.trigger( 'change:zones' );
},
save: function() {
if ( _.size( this.changes ) ) {
$.post( ajaxurl + '?action=woocommerce_shipping_zones_save_changes', {
wc_shipping_zones_nonce : data.wc_shipping_zones_nonce,
changes : this.changes
}, this.onSaveResponse, 'json' );
} else {
shippingZone.trigger( 'saved:zones' );
}
},
onSaveResponse: function( response, textStatus ) {
if ( 'success' === textStatus ) {
if ( response.success ) {
shippingZone.set( 'zones', response.data.zones );
shippingZone.trigger( 'change:zones' );
shippingZone.changes = {};
shippingZone.trigger( 'saved:zones' );
} else {
alert( data.strings.save_failed );
}
}
}
} ),
// Backbone view
ShippingZoneView = Backbone.View.extend({
rowTemplate: wp.template( 'wc-shipping-zone-row' ),
initialize: function() {
this.listenTo( this.model, 'change:zones', this.setUnloadConfirmation );
this.listenTo( this.model, 'saved:zones', this.clearUnloadConfirmation );
$tbody.on( 'change', { view: this }, this.updateModelOnChange );
$tbody.on( 'sortupdate', { view: this }, this.updateModelOnSort );
$( window ).on( 'beforeunload', { view: this }, this.unloadConfirmation );
$save_button.on( 'click', { view: this }, this.onSubmit );
$save_button.attr( 'disabled','disabled' );
$table.find( '.wc-shipping-zone-add' ).on( 'click', { view: this }, this.onAddNewRow );
},
render: function() {
var zones = _.indexBy( this.model.get( 'zones' ), 'zone_id' ),
view = this;
// Blank out the contents.
this.$el.empty();
if ( _.size( zones ) ) {
// Populate $tbody with the current zones
$.each( zones, function( id, rowData ) {
view.$el.append( view.rowTemplate( rowData ) );
} );
// Make the rows functiothis.$el.find( '.wc-shipping-zone-delete' ).on( 'click', { view: this }, this.onDeleteRow );
this.$el.find('.view').show();
this.$el.find('.edit').hide();
this.$el.find( '.wc-shipping-zone-edit' ).on( 'click', { view: this }, this.onEditRow );
this.$el.find( '.wc-shipping-zone-delete' ).on( 'click', { view: this }, this.onDeleteRow );
// Stripe
if ( _.size(zones) % 2 == 0 ) {
$table.find( 'tbody.wc-shipping-zone-rows').next('tbody').find('tr').addClass('odd');
} else {
$table.find( 'tbody.wc-shipping-zone-rows').next('tbody').find('tr').removeClass('odd');
}
}
},
onSubmit: function( event ) {
event.data.view.model.save();
event.data.view.render()
event.preventDefault();
},
onAddNewRow: function( event ) {
var view = event.data.view,
model = view.model,
zones = _.indexBy( model.get( 'zones' ), 'zone_id' ),
changes = {},
size = _.size( zones ),
newRow = _.extend( {}, data.default_zone, {
zone_id: 'new-' + size + '-' + Date.now(),
newRow: true
} );
newRow.zone_order = 1 + _.max(
_.pluck( zones, 'zone_order' ),
function ( val ) {
// Cast them all to integers, because strings compare funky. Sighhh.
return parseInt( val, 10 );
}
);
zones[ newRow.zone_id ] = newRow;
changes[ newRow.zone_id ] = newRow;
model.set( 'zones', zones );
model.logChanges( changes );
view.render();
return false;
},
onEditRow: function( event ) {
event.preventDefault();
$( this ).closest('tr').find('.view, .wc-shipping-zone-edit').hide();
$( this ).closest('tr').find('.edit').show();
event.data.view.model.trigger( 'change:zones' );
},
onDeleteRow: function( event ) {
var view = event.data.view,
model = view.model,
zones = _.indexBy( model.get( 'zones' ), 'zone_id' ),
changes = {},
zone_id = $( this ).closest('tr').data('id');
event.preventDefault();
delete zones[ zone_id ];
changes[ zone_id ] = _.extend( changes[ zone_id ] || {}, { deleted : 'deleted' } );
model.set( 'zones', zones );
model.logChanges( changes );
view.render();
},
setUnloadConfirmation: function() {
this.needsUnloadConfirm = true;
$save_button.removeAttr( 'disabled' );
},
clearUnloadConfirmation: function() {
this.needsUnloadConfirm = false;
$save_button.attr( 'disabled', 'disabled' );
},
unloadConfirmation: function( event ) {
if ( event.data.view.needsUnloadConfirm ) {
event.returnValue = data.strings.unload_confirmation_msg;
window.event.returnValue = data.strings.unload_confirmation_msg;
return data.strings.unload_confirmation_msg;
}
},
updateModelOnChange: function( event ) {
var model = event.data.view.model,
$target = $( event.target ),
zone_id = $target.closest( 'tr' ).data( 'id' ),
attribute = $target.data( 'attribute' ),
value = $target.val();
/*if ( 'city' === attribute || 'postcode' === attribute ) {
val = val.split( ';' );
val = $.map( val, function( thing ) {
return thing.trim();
});
}*/
var zones = _.indexBy( model.get( 'zones' ), 'zone_id' ),
changes = {};
if ( zones[ zone_id ][ attribute ] !== value ) {
changes[ zone_id ] = {};
changes[ zone_id ][ attribute ] = value;
zones[ zone_id ][ attribute ] = value;
}
model.logChanges( changes );
},
updateModelOnSort: function( event, ui ) {
var view = event.data.view,
model = view.model,
$tr = ui.item,
zone_id = $tr.data( 'id' ),
zones = _.indexBy( model.get( 'zones' ), 'zone_id' ),
old_position = zones[ zone_id ].zone_order,
new_position = $tr.index() + ( ( view.page - 1 ) * view.per_page ),
which_way = ( new_position > old_position ) ? 'higher' : 'lower',
changes = {},
zones_to_reorder, reordered_zones;
zones_to_reorder = _.filter( zones, function( rate ) {
var order = parseInt( rate.zone_order, 10 ),
limits = [ old_position, new_position ];
if ( parseInt( rate.zone_id, 10 ) === parseInt( zone_id, 10 ) ) {
return true;
} else if ( order > _.min( limits ) && order < _.max( limits ) ) {
return true;
} else if ( 'higher' === which_way && order === _.max( limits ) ) {
return true;
} else if ( 'lower' === which_way && order === _.min( limits ) ) {
return true;
}
return false;
} );
reordered_zones = _.map( zones_to_reorder, function( rate ) {
var order = parseInt( rate.zone_order, 10 );
if ( parseInt( rate.zone_id, 10 ) === parseInt( zone_id, 10 ) ) {
rate.zone_order = new_position;
} else if ( 'higher' === which_way ) {
rate.zone_order = order - 1;
} else if ( 'lower' === which_way ) {
rate.zone_order = order + 1;
}
changes[ rate.zone_id ] = _.extend( changes[ rate.zone_id ] || {}, { zone_order : rate.zone_order } );
return rate;
} );
if ( reordered_zones.length ) {
model.logChanges( changes );
view.render(); // temporary, probably should get yanked.
}
}
} ),
shippingZone = new ShippingZone({
zones: data.zones
} ),
shippingZoneView = new ShippingZoneView({
model: shippingZone,
el: $tbody
} );
shippingZoneView.render();
$tbody.sortable({
items: 'tr',
cursor: 'move',
axis: 'y',
handle: 'td.wc-shipping-zone-sort',
scrollSensitivity: 40
});
});
})( jQuery, shippingZonesLocalizeScript, wp, ajaxurl );

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -102,6 +102,7 @@ class WC_Admin_Assets {
wp_register_script( 'flot-pie', WC()->plugin_url() . '/assets/js/jquery-flot/jquery.flot.pie' . $suffix . '.js', array( 'jquery', 'flot' ), WC_VERSION ); wp_register_script( 'flot-pie', WC()->plugin_url() . '/assets/js/jquery-flot/jquery.flot.pie' . $suffix . '.js', array( 'jquery', 'flot' ), WC_VERSION );
wp_register_script( 'flot-stack', WC()->plugin_url() . '/assets/js/jquery-flot/jquery.flot.stack' . $suffix . '.js', array( 'jquery', 'flot' ), WC_VERSION ); wp_register_script( 'flot-stack', WC()->plugin_url() . '/assets/js/jquery-flot/jquery.flot.stack' . $suffix . '.js', array( 'jquery', 'flot' ), WC_VERSION );
wp_register_script( 'wc-settings-tax', WC()->plugin_url() . '/assets/js/admin/settings-views-html-settings-tax' . $suffix . '.js', array( 'jquery', 'wp-util', 'underscore', 'backbone' ), WC_VERSION ); wp_register_script( 'wc-settings-tax', WC()->plugin_url() . '/assets/js/admin/settings-views-html-settings-tax' . $suffix . '.js', array( 'jquery', 'wp-util', 'underscore', 'backbone' ), WC_VERSION );
wp_register_script( 'wc-shipping-zones', WC()->plugin_url() . '/assets/js/admin/wc-shipping-zones' . $suffix . '.js', array( 'jquery', 'wp-util', 'underscore', 'backbone', 'jquery-ui-sortable' ), WC_VERSION );
// Chosen is @deprecated (2.3) in favour of select2, but is registered for backwards compat // Chosen is @deprecated (2.3) in favour of select2, but is registered for backwards compat
wp_register_script( 'ajax-chosen', WC()->plugin_url() . '/assets/js/chosen/ajax-chosen.jquery' . $suffix . '.js', array( 'jquery', 'chosen' ), WC_VERSION ); wp_register_script( 'ajax-chosen', WC()->plugin_url() . '/assets/js/chosen/ajax-chosen.jquery' . $suffix . '.js', array( 'jquery', 'chosen' ), WC_VERSION );

View File

@ -23,6 +23,23 @@ class WC_Admin_Shipping_Zones {
public static function output() { public static function output() {
$allowed_countries = WC()->countries->get_allowed_countries(); $allowed_countries = WC()->countries->get_allowed_countries();
$continents = WC()->countries->get_continents(); $continents = WC()->countries->get_continents();
// Localize and enqueue our js.
wp_localize_script( 'wc-shipping-zones', 'shippingZonesLocalizeScript', array(
'zones' => WC_Shipping_Zones::get_zones(),
'default_zone' => array(
'zone_id' => 0,
'zone_name' => '',
'zone_order' => null,
),
'wc_shipping_zones_nonce' => wp_create_nonce( 'wc_shipping_zones_nonce' ),
'strings' => array(
'unload_confirmation_msg' => __( 'Your changed data will be lost if you leave this page without saving.', 'woocommerce' ),
'save_failed' => __( 'Your changes were not saved. Please retry.', 'woocommerce' )
),
) );
wp_enqueue_script( 'wc-shipping-zones' );
include_once( 'views/html-admin-page-shipping-zones.php' ); include_once( 'views/html-admin-page-shipping-zones.php' );
} }
} }

View File

@ -10,31 +10,18 @@
<th class="wc-shipping-zone-name">Zone Name</th> <th class="wc-shipping-zone-name">Zone Name</th>
<th class="wc-shipping-zone-region">Region(s)</th> <th class="wc-shipping-zone-region">Region(s)</th>
<th class="wc-shipping-zone-methods">Shipping Method(s)</th> <th class="wc-shipping-zone-methods">Shipping Method(s)</th>
<th class="wc-shipping-zone-remove">&nbsp;</th> <th class="wc-shipping-zone-actions">&nbsp;</th>
</tr> </tr>
</thead> </thead>
<tfoot> <tfoot>
<tr> <tr>
<td colspan="5"> <td colspan="5">
<a class="button button-secondary" href="#"><?php esc_html_e( 'Add shipping zone', 'woocommerce' ); ?></a> <a class="button button-secondary wc-shipping-zone-add" href="#"><?php esc_html_e( 'Add shipping zone', 'woocommerce' ); ?></a>
<input type="submit" class="button button-primary" value="Save shipping zones" /> <input type="submit" name="save" class="button button-primary" value="Save shipping zones" />
</td> </td>
</tr> </tr>
</tfoot> </tfoot>
<tbody> <tbody class="wc-shipping-zone-rows">
<tr>
<td width="1%" class="wc-shipping-zone-sort">
<input type="hidden" name="zone_order[]" value="">
</td>
<td class="wc-shipping-zone-name">
UK and Eire
</td>
<td>UK, Ireland</td>
<td>
<a href="#"><?php esc_html_e( 'Add a shipping method', 'woocommerce' ); ?></a>
</td>
<td width="1%"><a class="delete" href="#"><?php _e( 'Delete', 'woocommerce' ); ?></a></td>
</tr>
<tr> <tr>
<td width="1%" class="wc-shipping-zone-sort"> <td width="1%" class="wc-shipping-zone-sort">
<input type="hidden" name="zone_order[]" value=""> <input type="hidden" name="zone_order[]" value="">
@ -61,7 +48,7 @@
<a href="">Limit to specific states</a> | <a href="">Limit to specific zip codes</a> <a href="">Limit to specific states</a> | <a href="">Limit to specific zip codes</a>
</td> </td>
<td></td> <td></td>
<td width="1%"><a class="delete" href="#"><?php _e( 'Delete', 'woocommerce' ); ?></a></td> <td class="wc-shipping-zone-actions"><a class="delete" href="#"><?php _e( 'Delete', 'woocommerce' ); ?></a></td>
</tr> </tr>
</tbody> </tbody>
<tbody> <tbody>
@ -72,11 +59,28 @@
</td> </td>
<td class="wc-shipping-zone-region"><?php esc_html_e( 'Shipping methods added here apply to all regions without a zone.', 'woocommerce' ); ?></td> <td class="wc-shipping-zone-region"><?php esc_html_e( 'Shipping methods added here apply to all regions without a zone.', 'woocommerce' ); ?></td>
<td> <td>
<a href="#"><?php esc_html_e( 'Add a shipping method', 'woocommerce' ); ?></a> <a href="#" class="wc-shipping-zone-add-method button"><?php esc_html_e( 'Add a shipping method', 'woocommerce' ); ?></a>
</td>
<td class="wc-shipping-zone-actions">
<a class="wc-shipping-zone-delete" href="#"><?php _e( 'Delete', 'woocommerce' ); ?></a>
</td> </td>
<td width="1%"><a class="delete" href="#"><?php _e( 'Delete', 'woocommerce' ); ?></a></td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
</form> </form>
</div> </div>
<script type="text/html" id="tmpl-wc-shipping-zone-row">
<tr data-id="{{ data.zone_id }}">
<td width="1%" class="wc-shipping-zone-sort"></td>
<td class="wc-shipping-zone-name">
<div class="view">{{ data.zone_name }}</div>
<div class="edit"><input type="text" name="zone_name[ {{ data.zone_id }} ]" data-attribute="zone_name" value="{{ data.zone_name }}" placeholder="<?php esc_attr_e( 'Zone Name', 'woocommerce' ); ?>" /></div>
</td>
<td></td>
<td><a class="wc-shipping-zone-add-method button" href="#"><?php esc_html_e( 'Add a shipping method', 'woocommerce' ); ?></a></td>
<td class="wc-shipping-zone-actions">
<a class="wc-shipping-zone-delete" href="#"><?php _e( 'Delete', 'woocommerce' ); ?></a><a class="wc-shipping-zone-edit" href="#"><?php _e( 'Edit', 'woocommerce' ); ?></a>
</td>
</tr>
</script>

View File

@ -141,6 +141,7 @@ class WC_AJAX {
'save_variations' => false, 'save_variations' => false,
'bulk_edit_variations' => false, 'bulk_edit_variations' => false,
'tax_rates_save_changes' => false, 'tax_rates_save_changes' => false,
'shipping_zones_save_changes' => false,
); );
foreach ( $ajax_events as $ajax_event => $nopriv ) { foreach ( $ajax_events as $ajax_event => $nopriv ) {
@ -3019,6 +3020,55 @@ class WC_AJAX {
'rates' => WC_Tax::get_rates_for_tax_class( $current_class ), 'rates' => WC_Tax::get_rates_for_tax_class( $current_class ),
) ); ) );
} }
/**
* Handle submissions from assets/js/wc-shipping-zones.js Backbone model.
*/
public static function shipping_zones_save_changes() {
if ( ! isset( $_POST['wc_shipping_zones_nonce'], $_POST['changes'] ) ) {
wp_send_json_error( 'missing_fields' . (isset( $_POST['wc_shipping_zones_nonce'] ) ? 1 : 0). (isset( $_POST['changes'] ) ? 1 : 0) );
exit;
}
if ( ! wp_verify_nonce( $_POST['wc_shipping_zones_nonce'], 'wc_shipping_zones_nonce' ) ) {
wp_send_json_error( 'bad_nonce' );
exit;
}
// Check User Caps
if ( ! current_user_can( 'manage_woocommerce' ) ) {
wp_send_json_error( 'missing_capabilities' );
exit;
}
$changes = $_POST['changes'];
foreach ( $changes as $zone_id => $data ) {
if ( isset( $data['deleted'] ) ) {
if ( isset( $data['newRow'] ) ) {
// So the user added and deleted a new row.
// That's fine, it's not in the database anyways. NEXT!
continue;
}
WC_Shipping_Zones::delete_zone( $zone_id );
continue;
}
$zone_data = array_intersect_key( $data, array(
'zone_id' => 1,
'zone_name' => 1,
'zone_order' => 1
) );
$zone = new WC_Shipping_Zone( $zone_data['zone_id'] );
$zone->set_zone_name( $zone_data['zone_name'] );
$zone->set_zone_order( isset( $zone_data['zone_order'] ) ? $zone_data['zone_order'] : 0 );
$zone->save();
}
wp_send_json_success( array(
'zones' => WC_Shipping_Zones::get_zones(),
) );
}
} }
WC_AJAX::init(); WC_AJAX::init();

View File

@ -462,6 +462,22 @@ CREATE TABLE {$wpdb->prefix}woocommerce_tax_rate_locations (
KEY tax_rate_id (tax_rate_id), KEY tax_rate_id (tax_rate_id),
KEY location_type (location_type), KEY location_type (location_type),
KEY location_type_code (location_type(40),location_code(90)) KEY location_type_code (location_type(40),location_code(90))
) $collate;
CREATE TABLE {$wpdb->prefix}woocommerce_shipping_zones (
zone_id bigint(20) NOT NULL auto_increment,
zone_name varchar(255) NOT NULL,
zone_order bigint(20) NOT NULL,
PRIMARY KEY (zone_id)
) $collate;
CREATE TABLE {$wpdb->prefix}woocommerce_shipping_zone_locations (
location_id bigint(20) NOT NULL auto_increment,
zone_id bigint(20) NOT NULL,
location_code varchar(255) NOT NULL,
location_type varchar(40) NOT NULL,
PRIMARY KEY (location_id)
KEY location_id (tax_rate_id),
KEY location_type (location_type),
KEY location_type_code (location_type(40),location_code(90))
) $collate; ) $collate;
"; ";
} }

View File

@ -0,0 +1,244 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Represents a single shipping zone
*
* @class WC_Shipping_Zone
* @version 2.5.0
* @package WooCommerce/Classes
* @category Class
* @author WooThemes
*/
class WC_Shipping_Zone {
/**
* Zone Data
* @var array
*/
private $data = array(
'zone_id' => 0,
'zone_name' => '',
'zone_order' => 0,
'zone_locations' => array()
);
/**
* True when location data needs to be re-saved
* @var bool
*/
private $_locations_changed = false;
/**
* Constructor for zones
* @param int|object $zone Zone ID to load from the DB (optional) or already queried data.
*/
public function __construct( $zone = 0 ) {
if ( is_numeric( $zone ) && ! empty( $zone ) ) {
$this->read( $zone );
} elseif ( is_object( $zone ) ) {
$this->set_zone_id( $zone->zone_id );
$this->set_zone_name( $zone->zone_name );
$this->set_zone_order( $zone->zone_order );
$this->read_zone_locations( $zone->zone_id );
}
}
/**
* Get class data array
* @return array
*/
public function get_data() {
return $this->data;
}
/**
* Get zone ID
* @return int
*/
public function get_zone_id() {
return absint( $this->data['zone_id'] );
}
/**
* Get zone name
* @return string
*/
public function get_zone_name() {
return $this->data['zone_name'];
}
/**
* Get zone order
* @return int
*/
public function get_zone_order() {
return absint( $this->data['zone_order'] );
}
/**
* Get zone locations
* @return array of zone objects
*/
public function get_zone_locations() {
return $this->data['zone_locations'];
}
/**
* Set zone ID
* @access private
* @param int $set
*/
private function set_zone_id( $set ) {
$this->data['zone_id'] = absint( $set );
}
/**
* Set zone name
* @param string $set
*/
public function set_zone_name( $set ) {
$this->data['zone_name'] = wc_clean( $set );
}
/**
* Set zone order
* @param int $set
*/
public function set_zone_order( $set ) {
$this->data['zone_order'] = absint( $set );
}
/**
* Insert zone into the database
* @access private
* @param int Read zone data from DB
*/
private function read( $zone_id ) {
global $wpdb;
if ( $zone_data = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}woocommerce_shipping_zones WHERE zone_id = %d LIMIT 1;", $zone_id ) ) ) {
$this->set_zone_id( $zone_data->zone_id );
$this->set_zone_name( $zone_data->zone_name );
$this->set_zone_order( $zone_data->zone_order );
$this->read_zone_locations( $zone_data->zone_id );
}
}
/**
* Is passed location type valid?
* @param string $type
* @return boolean
*/
public function is_valid_location_type( $type ) {
return in_array( $type, array( 'postcode', 'state' ) );
}
/**
* Add location (state or postcode) to a zone.
* @param string $code
* @param string $type state or postcode
*/
public function add_location( $code, $type ) {
if ( is_valid_location_type( $type ) ) {
$location = array(
'code' => wc_clean( $code ),
'type' => wc_clean( $type )
);
$this->data['zone_locations'][] = (object) $location;
$this->_locations_changed = true;
}
}
/**
* Set locations
* @param array $locations Array of locations
*/
public function set_locations( $locations = array() ) {
$this->data['zone_locations'] = array();
foreach ( $locations as $location ) {
$this->add_location( $location['code'], $location['type'] );
}
$this->_locations_changed = true;
}
/**
* Read location data from the database
* @param int $zone_id
*/
private function read_zone_locations( $zone_id ) {
global $wpdb;
if ( $locations = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}woocommerce_shipping_zone_locations WHERE zone_id = %d LIMIT 1;", $zone_id ) ) ) {
foreach ( $locations as $location ) {
$this->add_location( $location->location_code, $location->location_type );
}
}
$this->_locations_changed = false;
}
/**
* Save zone data to the database
* @param array data to save for this zone
*/
public function save() {
$data = array(
'zone_name' => $this->get_zone_name(),
'zone_order' => $this->get_zone_order(),
);
if ( ! $this->get_zone_id() ) {
$this->create( $data );
} else {
$this->update( $data );
}
$this->save_locations();
}
/**
* Save locations to the DB
*
* This function clears old locations, then re-inserts new if any changes are found.
*/
private function save_locations() {
if ( ! $this->get_zone_id() || ! $this->_locations_changed ) {
return false;
}
$wpdb->delete( $wpdb->prefix . 'woocommerce_shipping_zone_locations', array( 'zone_id' => $this->get_zone_id() ) );
foreach ( $this->get_zone_locations() as $location ) {
$wpdb->insert( $wpdb->prefix . 'woocommerce_shipping_zone_locations', array(
'zone_id' => $this->get_zone_id(),
'location_code' => $location->code,
'location_type' => $location->type
) );
}
}
/**
* Insert zone into the database
* @access private
* @param array $zone_data data to save for this zone
*/
private function create( $zone_data ) {
global $wpdb;
$wpdb->insert( $wpdb->prefix . 'woocommerce_shipping_zones', $zone_data );
$this->set_zone_id( $wpdb->insert_id );
}
/**
* Update zone in the database
* @access private
* @param array $zone_data data to save for this zone
*/
public function update( $zone_data ) {
global $wpdb;
$wpdb->update( $wpdb->prefix . 'woocommerce_shipping_zones', $zone_data, array( 'zone_id' => $this->get_zone_id() ) );
}
}

View File

@ -0,0 +1,41 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Handles storage and retrieval of shipping zones
*
* @class WC_Shipping_Zones
* @version 2.5.0
* @package WooCommerce/Classes
* @category Class
* @author WooThemes
*/
class WC_Shipping_Zones {
/**
* Get shipping zones from the database
* @return [type] [description]
*/
public static function get_zones() {
global $wpdb;
$raw_zones = $wpdb->get_results( "SELECT zone_id, zone_name, zone_order FROM {$wpdb->prefix}woocommerce_shipping_zones;" );
$zones = array();
foreach ( $raw_zones as $raw_zone ) {
$zone = new WC_Shipping_Zone( $raw_zone );
$zones[] = $zone->get_data();
}
return $zones;
}
public static function delete_zone( $zone_id ) {
global $wpdb;
$wpdb->delete( $wpdb->prefix . 'woocommerce_shipping_zone_locations', array( 'zone_id' => $zone_id ) );
$wpdb->delete( $wpdb->prefix . 'woocommerce_shipping_zones', array( 'zone_id' => $zone_id ) );
}
}

View File

@ -263,6 +263,7 @@ final class WooCommerce {
include_once( 'includes/class-wc-form-handler.php' ); // Form Handlers include_once( 'includes/class-wc-form-handler.php' ); // Form Handlers
include_once( 'includes/class-wc-cart.php' ); // The main cart class include_once( 'includes/class-wc-cart.php' ); // The main cart class
include_once( 'includes/class-wc-tax.php' ); // Tax class include_once( 'includes/class-wc-tax.php' ); // Tax class
include_once( 'includes/class-wc-shipping-zones.php' ); // Shipping Zones class
include_once( 'includes/class-wc-customer.php' ); // Customer class include_once( 'includes/class-wc-customer.php' ); // Customer class
include_once( 'includes/class-wc-shortcodes.php' ); // Shortcodes class include_once( 'includes/class-wc-shortcodes.php' ); // Shortcodes class
include_once( 'includes/class-wc-https.php' ); // https Helper include_once( 'includes/class-wc-https.php' ); // https Helper