WC_Shipping_Zone_Data_Store

WC Shipping Zone Data Store.

Defined (1)

The class is defined in the following location(s).

/includes/data-stores/class-wc-shipping-zone-data-store.php  
  1. class WC_Shipping_Zone_Data_Store extends WC_Data_Store_WP implements WC_Shipping_Zone_Data_Store_Interface, WC_Object_Data_Store_Interface { 
  2.  
  3. /** 
  4. * Method to create a new shipping zone. 
  5. * @since 3.0.0 
  6. * @param WC_Shipping_Zone 
  7. */ 
  8. public function create( &$zone ) { 
  9. global $wpdb; 
  10. $wpdb->insert( $wpdb->prefix . 'woocommerce_shipping_zones', array( 
  11. 'zone_name' => $zone->get_zone_name(),  
  12. 'zone_order' => $zone->get_zone_order(),  
  13. ) ); 
  14. $zone->set_id( $wpdb->insert_id ); 
  15. $zone->save_meta_data(); 
  16. $this->save_locations( $zone ); 
  17. $zone->apply_changes(); 
  18. WC_Cache_Helper::incr_cache_prefix( 'shipping_zones' ); 
  19. WC_Cache_Helper::get_transient_version( 'shipping', true ); 
  20.  
  21. /** 
  22. * Update zone in the database. 
  23. * @since 3.0.0 
  24. * @param WC_Shipping_Zone 
  25. */ 
  26. public function update( &$zone ) { 
  27. global $wpdb; 
  28. if ( $zone->get_id() ) { 
  29. $wpdb->update( $wpdb->prefix . 'woocommerce_shipping_zones', array( 
  30. 'zone_name' => $zone->get_zone_name(),  
  31. 'zone_order' => $zone->get_zone_order(),  
  32. ), array( 'zone_id' => $zone->get_id() ) ); 
  33. $zone->save_meta_data(); 
  34. $this->save_locations( $zone ); 
  35. $zone->apply_changes(); 
  36. WC_Cache_Helper::incr_cache_prefix( 'shipping_zones' ); 
  37. WC_Cache_Helper::get_transient_version( 'shipping', true ); 
  38.  
  39. /** 
  40. * Method to read a shipping zone from the database. 
  41. * @since 3.0.0 
  42. * @param WC_Shipping_Zone 
  43. */ 
  44. public function read( &$zone ) { 
  45. global $wpdb; 
  46. if ( 0 === $zone->get_id() || "0" === $zone->get_id() ) { 
  47. $this->read_zone_locations( $zone ); 
  48. $zone->set_zone_name( __( 'Rest of the World', 'woocommerce' ) ); 
  49. $zone->read_meta_data(); 
  50. $zone->set_object_read( true ); 
  51. do_action( 'woocommerce_shipping_zone_loaded', $zone ); 
  52. } elseif ( $zone_data = $wpdb->get_row( $wpdb->prepare( "SELECT zone_name, zone_order FROM {$wpdb->prefix}woocommerce_shipping_zones WHERE zone_id = %d LIMIT 1;", $zone->get_id() ) ) ) { 
  53. $zone->set_zone_name( $zone_data->zone_name ); 
  54. $zone->set_zone_order( $zone_data->zone_order ); 
  55. $this->read_zone_locations( $zone ); 
  56. $zone->read_meta_data(); 
  57. $zone->set_object_read( true ); 
  58. do_action( 'woocommerce_shipping_zone_loaded', $zone ); 
  59. } else { 
  60. throw new Exception( __( 'Invalid data store.', 'woocommerce' ) ); 
  61.  
  62. /** 
  63. * Deletes a shipping zone from the database. 
  64. * @since 3.0.0 
  65. * @param WC_Shipping_Zone 
  66. * @param array $args Array of args to pass to the delete method. 
  67. * @return bool result 
  68. */ 
  69. public function delete( &$zone, $args = array() ) { 
  70. if ( $zone->get_id() ) { 
  71. global $wpdb; 
  72. $wpdb->delete( $wpdb->prefix . 'woocommerce_shipping_zone_methods', array( 'zone_id' => $zone->get_id() ) ); 
  73. $wpdb->delete( $wpdb->prefix . 'woocommerce_shipping_zone_locations', array( 'zone_id' => $zone->get_id() ) ); 
  74. $wpdb->delete( $wpdb->prefix . 'woocommerce_shipping_zones', array( 'zone_id' => $zone->get_id() ) ); 
  75. WC_Cache_Helper::incr_cache_prefix( 'shipping_zones' ); 
  76. $id = $zone->get_id(); 
  77. $zone->set_id( null ); 
  78. WC_Cache_Helper::incr_cache_prefix( 'shipping_zones' ); 
  79. WC_Cache_Helper::get_transient_version( 'shipping', true ); 
  80. do_action( 'woocommerce_delete_shipping_zone', $id ); 
  81.  
  82. /** 
  83. * Get a list of shipping methods for a specific zone. 
  84. * @since 3.0.0 
  85. * @param int $zone_id Zone ID 
  86. * @param bool $enabled_only True to request enabled methods only. 
  87. * @return array Array of objects containing method_id, method_order, instance_id, is_enabled 
  88. */ 
  89. public function get_methods( $zone_id, $enabled_only ) { 
  90. global $wpdb; 
  91. $raw_methods_sql = $enabled_only ? "SELECT method_id, method_order, instance_id, is_enabled FROM {$wpdb->prefix}woocommerce_shipping_zone_methods WHERE zone_id = %d AND is_enabled = 1;" : "SELECT method_id, method_order, instance_id, is_enabled FROM {$wpdb->prefix}woocommerce_shipping_zone_methods WHERE zone_id = %d;"; 
  92. return $wpdb->get_results( $wpdb->prepare( $raw_methods_sql, $zone_id ) ); 
  93.  
  94. /** 
  95. * Get count of methods for a zone. 
  96. * @since 3.0.0 
  97. * @param int Zone ID 
  98. * @return int Method Count 
  99. */ 
  100. public function get_method_count( $zone_id ) { 
  101. global $wpdb; 
  102. return $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->prefix}woocommerce_shipping_zone_methods WHERE zone_id = %d", $zone_id ) ); 
  103.  
  104. /** 
  105. * Add a shipping method to a zone. 
  106. * @since 3.0.0 
  107. * @param int $zone_id Zone ID 
  108. * @param string $type Method Type/ID 
  109. * @param int $order Method Order 
  110. * @return int Instance ID 
  111. */ 
  112. public function add_method( $zone_id, $type, $order ) { 
  113. global $wpdb; 
  114. $wpdb->insert( 
  115. $wpdb->prefix . 'woocommerce_shipping_zone_methods',  
  116. array( 
  117. 'method_id' => $type,  
  118. 'zone_id' => $zone_id,  
  119. 'method_order' => $order,  
  120. ),  
  121. array( 
  122. '%s',  
  123. '%d',  
  124. '%d',  
  125. ); 
  126. return $wpdb->insert_id; 
  127.  
  128. /** 
  129. * Delete a method instance. 
  130. * @since 3.0.0 
  131. * @param int $instance_id 
  132. */ 
  133. public function delete_method( $instance_id ) { 
  134. global $wpdb; 
  135. $wpdb->delete( $wpdb->prefix . 'woocommerce_shipping_zone_methods', array( 'instance_id' => $instance_id ) ); 
  136. do_action( 'woocommerce_delete_shipping_zone_method', $instance_id ); 
  137.  
  138. /** 
  139. * Get a shipping zone method instance. 
  140. * @since 3.0.0 
  141. * @param int 
  142. * @return object 
  143. */ 
  144. public function get_method( $instance_id ) { 
  145. global $wpdb; 
  146. return $wpdb->get_row( $wpdb->prepare( "SELECT zone_id, method_id, instance_id, method_order, is_enabled FROM {$wpdb->prefix}woocommerce_shipping_zone_methods WHERE instance_id = %d LIMIT 1;", $instance_id ) ); 
  147.  
  148. /** 
  149. * Find a matching zone ID for a given package. 
  150. * @since 3.0.0 
  151. * @param object $package 
  152. * @return int 
  153. */ 
  154. public function get_zone_id_from_package( $package ) { 
  155. global $wpdb; 
  156.  
  157. $country = strtoupper( wc_clean( $package['destination']['country'] ) ); 
  158. $state = strtoupper( wc_clean( $package['destination']['state'] ) ); 
  159. $continent = strtoupper( wc_clean( WC()->countries->get_continent_code_for_country( $country ) ) ); 
  160. $postcode = wc_normalize_postcode( wc_clean( $package['destination']['postcode'] ) ); 
  161.  
  162. // Work out criteria for our zone search 
  163. $criteria = array(); 
  164. $criteria[] = $wpdb->prepare( "( ( location_type = 'country' AND location_code = %s )", $country ); 
  165. $criteria[] = $wpdb->prepare( "OR ( location_type = 'state' AND location_code = %s )", $country . ':' . $state ); 
  166. $criteria[] = $wpdb->prepare( "OR ( location_type = 'continent' AND location_code = %s )", $continent ); 
  167. $criteria[] = "OR ( location_type IS NULL ) )"; 
  168.  
  169. // Postcode range and wildcard matching 
  170. $postcode_locations = $wpdb->get_results( "SELECT zone_id, location_code FROM {$wpdb->prefix}woocommerce_shipping_zone_locations WHERE location_type = 'postcode';" ); 
  171.  
  172. if ( $postcode_locations ) { 
  173. $zone_ids_with_postcode_rules = array_map( 'absint', wp_list_pluck( $postcode_locations, 'zone_id' ) ); 
  174. $matches = wc_postcode_location_matcher( $postcode, $postcode_locations, 'zone_id', 'location_code', $country ); 
  175. $do_not_match = array_unique( array_diff( $zone_ids_with_postcode_rules, array_keys( $matches ) ) ); 
  176.  
  177. if ( ! empty( $do_not_match ) ) { 
  178. $criteria[] = "AND zones.zone_id NOT IN (" . implode( ', ', $do_not_match ) . ")"; 
  179.  
  180. // Get matching zones 
  181. return $wpdb->get_var( " 
  182. SELECT zones.zone_id FROM {$wpdb->prefix}woocommerce_shipping_zones as zones 
  183. LEFT OUTER JOIN {$wpdb->prefix}woocommerce_shipping_zone_locations as locations ON zones.zone_id = locations.zone_id AND location_type != 'postcode' 
  184. WHERE " . implode( ' ', $criteria ) . " 
  185. ORDER BY zone_order ASC LIMIT 1 
  186. " ); 
  187.  
  188. /** 
  189. * Return an ordered list of zones. 
  190. * @since 3.0.0 
  191. * @return array An array of objects containing a zone_id, zone_name, and zone_order. 
  192. */ 
  193. public function get_zones() { 
  194. global $wpdb; 
  195. return $wpdb->get_results( "SELECT zone_id, zone_name, zone_order FROM {$wpdb->prefix}woocommerce_shipping_zones order by zone_order ASC;" ); 
  196.  
  197.  
  198. /** 
  199. * Return a zone ID from an instance ID. 
  200. * @since 3.0.0 
  201. * @param int 
  202. * @return int 
  203. */ 
  204. public function get_zone_id_by_instance_id( $id ) { 
  205. global $wpdb; 
  206. return $wpdb->get_var( $wpdb->prepare( "SELECT zone_id FROM {$wpdb->prefix}woocommerce_shipping_zone_methods as methods WHERE methods.instance_id = %d LIMIT 1;", $id ) ); 
  207.  
  208. /** 
  209. * Read location data from the database. 
  210. * @param WC_Shipping_Zone 
  211. */ 
  212. private function read_zone_locations( &$zone ) { 
  213. global $wpdb; 
  214. if ( $locations = $wpdb->get_results( $wpdb->prepare( "SELECT location_code, location_type FROM {$wpdb->prefix}woocommerce_shipping_zone_locations WHERE zone_id = %d;", $zone->get_id() ) ) ) { 
  215. foreach ( $locations as $location ) { 
  216. $zone->add_location( $location->location_code, $location->location_type ); 
  217.  
  218. /** 
  219. * Save locations to the DB. 
  220. * This function clears old locations, then re-inserts new if any changes are found. 
  221. * @since 3.0.0 
  222. * @param WC_Shipping_Zone 
  223. */ 
  224. private function save_locations( &$zone ) { 
  225. $updated_props = array(); 
  226. $changed_props = array_keys( $zone->get_changes() ); 
  227. if ( ! in_array( 'zone_locations', $changed_props ) ) { 
  228. return false; 
  229.  
  230. global $wpdb; 
  231. $wpdb->delete( $wpdb->prefix . 'woocommerce_shipping_zone_locations', array( 'zone_id' => $zone->get_id() ) ); 
  232.  
  233. foreach ( $zone->get_zone_locations( 'edit' ) as $location ) { 
  234. $wpdb->insert( $wpdb->prefix . 'woocommerce_shipping_zone_locations', array( 
  235. 'zone_id' => $zone->get_id(),  
  236. 'location_code' => $location->code,  
  237. 'location_type' => $location->type,  
  238. ) );