PATH:
home
/
letacommog
/
rdvenunclick.fr1
/
wp-content
/
plugins
/
dokan-pro
/
includes
/
Shipping
<?php namespace WeDevs\DokanPro\Shipping; /** * Dokan Shipping Zone Class * * @package dokan */ class ShippingZone { /** * Get All Zone * * @since 1.0.0 * * @return void */ public static function get_zones() { $data_store = \WC_Data_Store::load( 'shipping-zone' ); $raw_zones = $data_store->get_zones(); $zones = array(); $seller_id = dokan_get_current_user_id(); foreach ( $raw_zones as $raw_zone ) { $zone = new \WC_Shipping_Zone( $raw_zone ); $enabled_methods = $zone->get_shipping_methods( true ); $methods_id = wp_list_pluck( $enabled_methods, 'id' ); if ( in_array( 'dokan_vendor_shipping', $methods_id ) ) { $zones[ $zone->get_id() ] = $zone->get_data(); $zones[ $zone->get_id() ]['zone_id'] = $zone->get_id(); $zones[ $zone->get_id() ]['formatted_zone_location'] = $zone->get_formatted_location(); $zones[ $zone->get_id() ]['shipping_methods'] = self::get_shipping_methods( $zone->get_id(), $seller_id ); } } // Everywhere zone if has method called vendor shipping $overall_zone = new \WC_Shipping_Zone(0); $enabled_methods = $overall_zone->get_shipping_methods( true ); $methods_id = wp_list_pluck( $enabled_methods, 'id' ); if ( in_array( 'dokan_vendor_shipping', $methods_id ) ) { $zones[ $overall_zone->get_id() ] = $overall_zone->get_data(); $zones[ $overall_zone->get_id() ]['zone_id'] = $overall_zone->get_id(); $zones[ $overall_zone->get_id() ]['formatted_zone_location'] = $overall_zone->get_formatted_location(); $zones[ $overall_zone->get_id() ]['shipping_methods'] = self::get_shipping_methods( $overall_zone->get_id(), $seller_id ); } return $zones; } /** * Get single zone info * * @since 2.8.0 * * @return void */ public static function get_zone( $zone_id ) { $zone = array(); $seller_id = dokan_get_current_user_id(); $zone_obj = \WC_Shipping_Zones::get_zone_by( 'zone_id', $zone_id ); $zone['data'] = $zone_obj->get_data(); $zone['formatted_zone_location'] = $zone_obj->get_formatted_location(); $zone['shipping_methods'] = self::get_shipping_methods( $zone_id, $seller_id ); $zone['locations'] = self::get_locations( $zone_id ); return $zone; } /** * Add Shipping Method for a zone * * @since 2.8.0 * * @return void */ public static function add_shipping_methods( $data ) { global $wpdb; $table_name = "{$wpdb->prefix}dokan_shipping_zone_methods"; if ( empty( $data['method_id'] ) ) { return new \WP_Error( 'no-method-id', __( 'No shipping method found for adding', 'dokan' ) ); } $result = $wpdb->insert( $table_name, array( 'method_id' => $data['method_id'], 'zone_id' => $data['zone_id'], 'seller_id' => dokan_get_current_user_id(), 'is_enabled' => 1, 'settings' => maybe_serialize( $data['settings'] ) ), array( '%s', '%d', '%d', '%d', '%s' ) ); if ( ! $result ) { return new \WP_Error( 'method-not-added', __( 'Shipping method not added successfully', 'dokan' ) ); } return $wpdb->insert_id; } /** * Delete shipping method * * @since 2.8.0 * * @return void */ public static function delete_shipping_methods( $data ) { global $wpdb; $table_name = "{$wpdb->prefix}dokan_shipping_zone_methods"; $result = $wpdb->query( $wpdb->prepare( "DELETE FROM {$table_name} WHERE zone_id=%d AND seller_id=%d AND instance_id=%d", $data['zone_id'], dokan_get_current_user_id(), $data['instance_id'] ) ); if ( ! $result ) { return new \WP_Error( 'method-not-deleted', __( 'Shipping method not deleted', 'dokan' ) ); } return $result; } /** * Get Shipping Methods for a zone * * @since 2.8.0 * * @return void */ public static function get_shipping_methods( $zone_id, $seller_id ) { global $wpdb; $sql = "SELECT * FROM {$wpdb->prefix}dokan_shipping_zone_methods WHERE `zone_id`={$zone_id} AND `seller_id`={$seller_id}"; $results = $wpdb->get_results( $sql ); $method = array(); foreach ( $results as $key => $result ) { $default_settings = array( 'title' => self::get_method_label( $result->method_id ), 'description' => __( 'Lets you charge a rate for shipping', 'dokan' ), 'cost' => '0', 'tax_status' => 'none' ); $method_id = $result->method_id .':'. $result->instance_id; $settings = ! empty( $result->settings ) ? maybe_unserialize( $result->settings ) : array(); $settings = wp_parse_args( $settings, $default_settings ); $method[$method_id]['instance_id'] = $result->instance_id; $method[$method_id]['id'] = $result->method_id; $method[$method_id]['enabled'] = ( $result->is_enabled ) ? 'yes' : 'no'; $method[$method_id]['title'] = $settings['title']; $method[$method_id]['settings'] = array_map( 'stripslashes_deep', maybe_unserialize( $settings ) ); } return $method; } /** * Update shipping method settings * * @since 2.8.0 * * @return void */ public static function update_shipping_method( $args ) { global $wpdb; $data = array( 'method_id' => $args['method_id'], 'zone_id' => $args['zone_id'], 'seller_id' => empty( $args['seller_id'] ) ? dokan_get_current_user_id() : $args['seller_id'], 'settings' => maybe_serialize( $args['settings'] ) ); $table_name = "{$wpdb->prefix}dokan_shipping_zone_methods"; $updated = $wpdb->update( $table_name, $data, array( 'instance_id' => $args['instance_id' ] ), array( '%s', '%d', '%d', '%s' ) ); if ( $updated ) { return $data; } return false; } /** * Toggle shipping method * * @since 2.8.0 * * @return void */ public static function toggle_shipping_method( $data ) { global $wpdb; $table_name = "{$wpdb->prefix}dokan_shipping_zone_methods"; $updated = $wpdb->update( $table_name, array( 'is_enabled' => $data['checked'] ), array( 'instance_id' => $data['instance_id' ], 'zone_id' => $data['zone_id'], 'seller_id' => dokan_get_current_user_id() ), array( '%d' ) ); if ( ! $updated ) { return new \WP_Error( 'method-not-toggled', __( 'Method enable or disable not working', 'dokan' ) ); } return true; } /** * Get zone locations * * @since 2.8.0 * * @return void */ public static function get_locations( $zone_id, $seller_id = null ) { global $wpdb; $table_name = "{$wpdb->prefix}dokan_shipping_zone_locations"; if ( ! $seller_id ) { $seller_id = dokan_get_current_user_id(); } $sql = "SELECT * FROM {$table_name} WHERE zone_id=$zone_id AND seller_id=$seller_id"; $results = $wpdb->get_results( $sql ); $locations = array(); if ( $results ) { foreach ( $results as $key => $result ) { $locations[] = array( 'code' => $result->location_code, 'type' => $result->location_type ); } } return $locations; } /** * Save zone location for seller * * @since 2.8.0 * * @return void */ public static function save_location( $location, $zone_id ) { global $wpdb; // Setup arrays for Actual Values, and Placeholders $values = array(); $place_holders = array(); $seller_id = dokan_get_current_user_id(); $table_name = "{$wpdb->prefix}dokan_shipping_zone_locations"; $query = "INSERT INTO {$table_name} (seller_id, zone_id, location_code, location_type) VALUES "; if ( ! empty( $location ) ) { foreach( $location as $key => $value ) { array_push( $values, $seller_id, $zone_id, $value['code'], $value['type'] ); $place_holders[] = "('%d', '%d', '%s', '%s')"; } $query .= implode(', ', $place_holders); $wpdb->query( $wpdb->prepare( "DELETE FROM {$table_name} WHERE zone_id=%d AND seller_id=%d", $zone_id, $seller_id ) ); if ( $wpdb->query( $wpdb->prepare( "$query ", $values ) ) ) { return true; } } else { if( $wpdb->query( $wpdb->prepare( "DELETE FROM {$table_name} WHERE zone_id=%d AND seller_id=%d", $zone_id, $seller_id ) ) ) { return true; } } return false; } /** * get Shipping method label * * @since 2.8.0 * * @return void */ public static function get_method_label( $method_id ) { if ( 'flat_rate' == $method_id ) { return __( 'Flat Rate', 'dokan' ); } elseif ( 'local_pickup' == $method_id ) { return __( 'Local Pickup', 'dokan' ); } elseif( 'free_shipping' == $method_id ) { return __( 'Free Shipping', 'dokan' ); } else { return __( 'Custom Shipping', 'dokan' ); } } /** * Find a matching zone for a given package. * * @param array $package Shipping package. * * @return WC_Shipping_Zone */ public static function get_zone_matching_package( $package ) { $country = strtoupper( wc_clean( $package['destination']['country'] ) ); $state = strtoupper( wc_clean( $package['destination']['state'] ) ); $postcode = wc_normalize_postcode( wc_clean( $package['destination']['postcode'] ) ); $cache_key = \WC_Cache_Helper::get_cache_prefix( 'shipping_zones' ) . 'dokan_shipping_zone_' . md5( sprintf( '%s+%s+%s+%d', $country, $state, $postcode, $package['seller_id'] ) ); $matching_zone_id = wp_cache_get( $cache_key, 'shipping_zones' ); if ( false === $matching_zone_id ) { $matching_zone_id = self::get_zone_id_from_package( $package ); wp_cache_set( $cache_key, $matching_zone_id, 'shipping_zones' ); } return new \WC_Shipping_Zone( $matching_zone_id ? $matching_zone_id : 0 ); } /** * Find a matching zone ID for a given package. * * @param object $package Package information. * * @return int */ public static function get_zone_id_from_package( $package ) { global $wpdb; $country = strtoupper( wc_clean( $package['destination']['country'] ) ); $state = strtoupper( wc_clean( $package['destination']['state'] ) ); $continent = strtoupper( wc_clean( WC()->countries->get_continent_code_for_country( $country ) ) ); $postcode = wc_normalize_postcode( wc_clean( $package['destination']['postcode'] ) ); $vendor_id = self::get_vendor_id_from_package( $package ); // Work out criteria for our zone search. $criteria = array(); $criteria[] = $wpdb->prepare( "( ( locations.location_type = 'country' AND locations.location_code = %s )", $country ); $criteria[] = $wpdb->prepare( "OR ( locations.location_type = 'state' AND locations.location_code = %s )", $country . ':' . $state ); $criteria[] = $wpdb->prepare( "OR ( locations.location_type = 'continent' AND locations.location_code = %s )", $continent ); $criteria[] = 'OR ( locations.location_type IS NULL ) )'; // Postcode range and wildcard matching. $postcode_locations = $wpdb->get_results( "SELECT zone_id, location_code FROM {$wpdb->prefix}dokan_shipping_zone_locations WHERE location_type = 'postcode' AND seller_id = {$vendor_id}" ); if ( $postcode_locations ) { $zone_ids_with_postcode_rules = array_map( 'absint', wp_list_pluck( $postcode_locations, 'zone_id' ) ); $matches = wc_postcode_location_matcher( $postcode, $postcode_locations, 'zone_id', 'location_code', $country ); $do_not_match = array_unique( array_diff( $zone_ids_with_postcode_rules, array_keys( $matches ) ) ); if ( ! empty( $do_not_match ) ) { $criteria[] = 'AND locations.zone_id NOT IN (' . implode( ',', $do_not_match ) . ')'; } } $criteria = implode( ' ', $criteria ); $shipping_zone_ids = $wpdb->get_col( "SELECT locations.zone_id FROM {$wpdb->prefix}dokan_shipping_zone_locations as locations LEFT JOIN {$wpdb->prefix}dokan_shipping_zone_methods as methods ON locations.zone_id = methods.zone_id LEFT JOIN {$wpdb->prefix}woocommerce_shipping_zones as wc_zones ON locations.zone_id = wc_zones.zone_id WHERE methods.is_enabled = 1 AND methods.settings IS NOT NULL AND wc_zones.zone_id IS NOT NULL AND locations.seller_id = {$vendor_id} AND {$criteria} GROUP BY locations.zone_id ORDER BY wc_zones.zone_order ASC" ); $shipping_zones = []; $zone_id_from_package = 0; $customer_country_state = $country . ':' . $state; if ( ! empty( $shipping_zone_ids ) ) { $zone_locations = $wpdb->get_results( "SELECT locations.zone_id, locations.location_code, locations.location_type FROM {$wpdb->prefix}dokan_shipping_zone_locations as locations LEFT JOIN {$wpdb->prefix}woocommerce_shipping_zones as wc_zones ON locations.zone_id = wc_zones.zone_id WHERE seller_id={$vendor_id} AND locations.zone_id IN (" . implode( ', ', $shipping_zone_ids ) . ") ORDER BY wc_zones.zone_order ASC", ARRAY_A ); if ( ! empty( $zone_locations ) ) { foreach( $zone_locations as $location ) { $zone_id = $location['zone_id']; if ( ! isset( $shipping_zones[ $zone_id ] ) ) { $shipping_zones[ $zone_id ] = [ 'zone_id' => $zone_id, 'continent' => [], 'country' => [], 'state' => [], 'postcode' => [], ]; } if ( 'postcode' === $location['location_type'] ) { $shipping_zones[ $zone_id ]['postcode'][] = (object) [ 'zone_id' => $zone_id, 'location_code' => $location['location_code'], ]; } else { $shipping_zones[ $zone_id ][ $location['location_type'] ][] = $location['location_code']; } } // Use cases similar to Truth Table $use_cases = [ // Continent, Country, State, Postcode [ 1, 1, 1, 1 ], [ 0, 1, 1, 1 ], [ 1, 0, 1, 1 ], [ 0, 0, 1, 1 ], [ 1, 1, 0, 1 ], [ 0, 1, 0, 1 ], [ 1, 0, 0, 1 ], [ 0, 0, 0, 1 ], [ 1, 1, 1, 0 ], [ 0, 1, 1, 0 ], [ 1, 0, 1, 0 ], [ 0, 0, 1, 0 ], [ 1, 1, 0, 0 ], [ 0, 1, 0, 0 ], [ 1, 0, 0, 0 ], [ 0, 0, 0, 0 ] ]; foreach( $shipping_zones as $shipping_zone ) { foreach( $use_cases as $use_case ) { if ( $use_case[0] ) { $check_continent = in_array( $continent, $shipping_zone['continent'] ); } else { $check_continent = empty( $shipping_zone['continent'] ); } if ( $use_case[1] ) { $check_country = in_array( $country, $shipping_zone['country'] ); } else { $check_country = empty( $shipping_zone['country'] ); } if ( $use_case[2] ) { $check_state = in_array( $customer_country_state, $shipping_zone['state'] ); } else { $check_state = empty( $shipping_zone['state'] ); } if ( $use_case[3] ) { $matches = wc_postcode_location_matcher( $postcode, $shipping_zone['postcode'], 'zone_id', 'location_code', $country ); reset( $matches ); $matched_zone_id = key( $matches ); $check_postcode = absint( $matched_zone_id ) === absint( $shipping_zone['zone_id'] ); } else { $check_postcode = empty( $shipping_zone['postcode'] ); } if ( $check_postcode && $check_state && $check_country && $check_continent ) { $zone_id_from_package = $shipping_zone['zone_id']; break; } } if ( $zone_id_from_package ) { break; } } } } if ( ! $zone_id_from_package ) { $zone_id_from_package = $wpdb->get_var( "SELECT `zone`.`zone_id` FROM `{$wpdb->prefix}woocommerce_shipping_zones` as `zone` LEFT JOIN {$wpdb->prefix}dokan_shipping_zone_locations as `location` on `zone`.`zone_id` = `location`.`zone_id` LEFT JOIN {$wpdb->prefix}dokan_shipping_zone_methods as method on `zone`.`zone_id` = `method`.`zone_id` WHERE `location`.`zone_id` is NULL AND `method`.`is_enabled` = 1 AND `method`.`seller_id` = {$vendor_id} ORDER BY zone.zone_order ASC LIMIT 1" ); } return apply_filters( 'dokan_get_zone_id_from_package', $zone_id_from_package, $package ); } /** * Get vendor id from package * * @param int $package * * @return int */ public static function get_vendor_id_from_package( $package ) { if ( ! $package ) { return 0; } $vendor_id = isset( $package['seller_id'] ) ? $package['seller_id'] : ''; if ( ! $vendor_id ) { return 0; } return $vendor_id; } /** * Get all the zone ids of a vendor * * @param object $package * * @return array */ public static function get_vendor_all_zone_ids( $package ) { global $wpdb; $vendor_id = isset( $package['seller_id'] ) ? $package['seller_id'] : ''; if ( ! $vendor_id ) { return 0; } $table_name = "{$wpdb->prefix}dokan_shipping_zone_methods"; $results = $wpdb->get_results( $wpdb->prepare( "SELECT zone_id FROM {$table_name} WHERE seller_id=%d", $vendor_id ) ); $zone_ids = array_map( function( $zone ) { return (int) $zone->zone_id; }, $results ); return apply_filters( 'dokan_get_vendor_all_zone_ids', $zone_ids, $package ); } /** * Get zone id by postcode * * @since 2.9.14 * * @param int $postcode * @param int $vendor_id Deprecated * * @return int|false on failure */ public static function get_zone_id_by_postcode( $postcode, $vendor_id = false ) { global $wpdb; if ( $vendor_id ) { /** * We had to deprecate `vendor_id` cause, we may have multiple vendor on the cart, whith different postcode. * Suppose Vendor_One ships porduct to zip code 10001 and Vendor_Two ships to 10002. If customer inserts 10002 and Vendor_Two's * Product is in the bottom on the cart then shipping won't be available for Vendor_Two as Vendor_One's shipping is false. So we will have to show Vendor_Two's available shipping anyway. */ wc_deprecated_argument( 'vendor_id', '3.0.0', __CLASS__ . '::get_zone_id_by_postcode() doesn\'t require $vendor_id anymore.' ); } $wc_shipping_zones = "{$wpdb->prefix}woocommerce_shipping_zones"; $dokan_shipping_zones = "{$wpdb->prefix}dokan_shipping_zone_locations"; $vendor_zone_id = $wpdb->get_var( $wpdb->prepare( "SELECT zone_id FROM {$dokan_shipping_zones} WHERE location_code=%s AND location_type=%s", $postcode, 'postcode' ) ); /** * We are making sure that `vendor_zone_id` is exsits in woocommerce_zone_ids to avoid `Uncaught Exception: Invalid data store`. * * @since 3.0.0 */ $wc_zone_ids = $wpdb->get_results( "select zone_id from {$wc_shipping_zones}" ); $wc_zone_ids = array_map( function( $zone ) { return intval( $zone->zone_id ); }, $wc_zone_ids ); $zone_id = in_array( $vendor_zone_id, $wc_zone_ids ) ? $vendor_zone_id : ''; return apply_filters( 'dokan_get_zone_id_by_postcode', $zone_id, $postcode ); } }
[+]
..
[+]
Methods
[-] Hooks.php
[edit]
[-] ShippingZone.php
[edit]