feat: Add Shipping API controller

Created backend API for fetching WooCommerce shipping zones.

New Files:
- includes/Api/ShippingController.php

Features:
 GET /settings/shipping/zones endpoint
 Fetches all WooCommerce shipping zones
 Includes shipping methods for each zone
 Handles "Rest of the World" zone (zone 0)
 Returns formatted region names
 Returns method costs (Free, Calculated, or price)
 Permission check: manage_woocommerce

Data Structure:
- id: Zone ID
- name: Zone name
- order: Display order
- regions: Comma-separated region names
- rates: Array of shipping methods
  - id: Method instance ID
  - name: Method title
  - price: Formatted price or "Free"/"Calculated"
  - enabled: Boolean

Integration:
- Registered in Routes.php
- Uses WC_Shipping_Zones API
- Compatible with all WooCommerce shipping methods
This commit is contained in:
dwindown
2025-11-08 21:27:34 +07:00
parent e8b4421950
commit bc7206f1cc
2 changed files with 158 additions and 0 deletions

View File

@@ -9,6 +9,7 @@ use WooNooW\Api\AnalyticsController;
use WooNooW\Api\AuthController;
use WooNooW\API\PaymentsController;
use WooNooW\API\StoreController;
use WooNooW\Api\ShippingController;
class Routes {
public static function init() {
@@ -49,6 +50,10 @@ class Routes {
// Store controller
$store_controller = new StoreController();
$store_controller->register_routes();
// Shipping controller
$shipping_controller = new ShippingController();
$shipping_controller->register_routes();
});
}
}

View File

@@ -0,0 +1,153 @@
<?php
namespace WooNooW\Api;
use WP_REST_Request;
use WP_REST_Response;
use WC_Shipping_Zones;
class ShippingController extends BaseController {
protected $namespace = 'woonoow/v1';
protected $rest_base = 'settings/shipping';
public function register_routes() {
// Get shipping zones
register_rest_route(
$this->namespace,
'/' . $this->rest_base . '/zones',
array(
array(
'methods' => \WP_REST_Server::READABLE,
'callback' => array( $this, 'get_zones' ),
'permission_callback' => array( $this, 'check_permission' ),
),
)
);
}
/**
* Get all shipping zones with their methods
*/
public function get_zones( WP_REST_Request $request ) {
try {
$zones_data = array();
// Get all shipping zones
$zones = WC_Shipping_Zones::get_zones();
foreach ( $zones as $zone_data ) {
$zone = WC_Shipping_Zones::get_zone( $zone_data['id'] );
// Get zone locations (regions)
$locations = $zone->get_zone_locations();
$regions = array();
foreach ( $locations as $location ) {
if ( $location->type === 'country' ) {
$countries = WC()->countries->get_countries();
$regions[] = $countries[ $location->code ] ?? $location->code;
} elseif ( $location->type === 'state' ) {
$states = WC()->countries->get_states( substr( $location->code, 0, 2 ) );
$regions[] = $states[ substr( $location->code, 3 ) ] ?? $location->code;
} elseif ( $location->type === 'continent' ) {
$continents = WC()->countries->get_continents();
$regions[] = $continents[ $location->code ]['name'] ?? $location->code;
} elseif ( $location->type === 'postcode' ) {
$regions[] = 'Postcode: ' . $location->code;
}
}
// Get shipping methods for this zone
$shipping_methods = $zone->get_shipping_methods( true ); // true = enabled only
$rates = array();
foreach ( $shipping_methods as $method ) {
$rate = array(
'id' => $method->id . ':' . $method->instance_id,
'instance_id' => $method->instance_id,
'method_id' => $method->id,
'name' => $method->get_title(),
'enabled' => $method->enabled === 'yes',
);
// Get cost if available
if ( isset( $method->cost ) && $method->cost !== '' ) {
$rate['price'] = wc_price( $method->cost );
} elseif ( $method->id === 'free_shipping' ) {
$rate['price'] = __( 'Free', 'woonoow' );
} else {
$rate['price'] = __( 'Calculated', 'woonoow' );
}
// Get method description if available
if ( method_exists( $method, 'get_method_description' ) ) {
$rate['description'] = $method->get_method_description();
}
$rates[] = $rate;
}
$zones_data[] = array(
'id' => $zone_data['id'],
'name' => $zone->get_zone_name(),
'order' => $zone->get_zone_order(),
'regions' => ! empty( $regions ) ? implode( ', ', $regions ) : __( 'No regions', 'woonoow' ),
'rates' => $rates,
);
}
// Add "Rest of the World" zone (zone 0)
$zone_0 = new \WC_Shipping_Zone( 0 );
$shipping_methods = $zone_0->get_shipping_methods( true );
$rates = array();
foreach ( $shipping_methods as $method ) {
$rate = array(
'id' => $method->id . ':' . $method->instance_id,
'instance_id' => $method->instance_id,
'method_id' => $method->id,
'name' => $method->get_title(),
'enabled' => $method->enabled === 'yes',
);
if ( isset( $method->cost ) && $method->cost !== '' ) {
$rate['price'] = wc_price( $method->cost );
} elseif ( $method->id === 'free_shipping' ) {
$rate['price'] = __( 'Free', 'woonoow' );
} else {
$rate['price'] = __( 'Calculated', 'woonoow' );
}
$rates[] = $rate;
}
if ( ! empty( $rates ) ) {
$zones_data[] = array(
'id' => 0,
'name' => __( 'Rest of the World', 'woonoow' ),
'order' => 9999,
'regions' => __( 'Locations not covered by other zones', 'woonoow' ),
'rates' => $rates,
);
}
return new WP_REST_Response( $zones_data, 200 );
} catch ( \Exception $e ) {
return new WP_REST_Response(
array(
'error' => 'fetch_failed',
'message' => $e->getMessage(),
),
500
);
}
}
/**
* Check if user has permission to manage shipping
*/
public function check_permission() {
return current_user_can( 'manage_woocommerce' );
}
}