wpdesk/abstract-shipping

2.11.0 2022-08-16 15:25 UTC

README

pipeline status coverage report Latest Stable Version Total Downloads Latest Unstable Version License

Abstract Shipping

A library containing interfaces, abstracts and basic implementations to be used for WordPress/WooCommerce shipping plugins.

Requirements

PHP 7.0 or later.

Installation via Composer

In order to install the bindings via Composer run the following command:

composer require wpdesk/abstract-shipping

Example usage

Creating a shipment from WooCommerce cart contents

/**
 * Build raw shipping data from WooCommerce
 *
 * @package WPDesk\ShippingBuilder
 */
class WooCommerceShippingBuilder {

	/**
	 * Sender address
	 *
	 * @var AddressProvider
	 */
	private $sender_address;

	/**
	 * Sender address
	 *
	 * @var AddressProvider
	 */
	private $receiver_address;

	/**
	 * WooCommerce Package
	 *
	 * @var array
	 */
	protected $package;

	/**
	 * Dimension unit.
	 *
	 * @var string
	 */
	private $dimension_unit;

	/**
	 * Weight unit.
	 *
	 * @var string
	 */
	private $weight_unit;

	/**
	 * Currency for items.
	 *
	 * @var string
	 */
	protected $currency;

	/**
	 * Rounding precision.
	 *
	 * @var int
	 */
	private $rounding_precision;

	/**
	 * @param AddressProvider $sender_address Sender address.
	 */
	public function set_sender_address( AddressProvider $sender_address ) {
		$this->sender_address = $sender_address;
	}

	/**
	 * @param AddressProvider $receiver_address Receiver address.
	 */
	public function set_receiver_address( AddressProvider $receiver_address ) {
		$this->receiver_address = $receiver_address;
	}

	/**
	 * @param string $dimension_unit Dimension unit.
	 */
	public function set_dimension_unit( $dimension_unit ) {
		$this->dimension_unit = $dimension_unit;
	}

	/**
	 * @param string $weight_unit Weight unit.
	 */
	public function set_weight_unit( $weight_unit ) {
		$this->weight_unit = $weight_unit;
	}

	/**
	 * @param string $currency Currency for items.
	 */
	public function set_currency( $currency ) {
		$this->currency = $currency;
	}

	/**
	 * @param int $rounding_precision Rounding precision.
	 */
	public function set_rounding_precision( $rounding_precision ) {
		$this->rounding_precision = $rounding_precision;
	}

	/**
	 * Sets WooCommerce Package to build.
	 *
	 * @param array $package Package.
	 */
	public function set_woocommerce_package( array $package ) {
		$this->package = $package;
	}

	/**
	 * Returns WooCommerce package that is used to build shipment.
	 *
	 * @return array
	 *
	 * @deprecated Try not to use it. Better use built shipment.
	 */
	public function get_woocommerce_package() {
		return $this->package;
	}

	/**
	 * Get dimension unit.
	 *
	 * @return string
	 */
	protected function get_woocommerce_dimension_unit() {
		switch ( $this->dimension_unit ) {
			case 'mm':
				return Dimensions::DIMENSION_UNIT_MM;
			case 'cm':
				return Dimensions::DIMENSION_UNIT_CM;
			case 'm':
				return Dimensions::DIMENSION_UNIT_M;
			case 'in':
				return Dimensions::DIMENSION_UNIT_IN;
		}

		return $this->dimension_unit;
	}

	/**
	 * Get weight unit.
	 *
	 * @return string
	 */
	protected function get_woocommerce_weight_unit() {
		switch ( $this->weight_unit ) {
			case 'g':
				return Weight::WEIGHT_UNIT_G;
			case 'kg':
				return Weight::WEIGHT_UNIT_KG;
			case 'lb':
				return Weight::WEIGHT_UNIT_LB;
		}

		return $this->weight_unit;
	}

	/**
	 * Get weight.
	 *
	 * @param array $package_item Package item.
	 *
	 * @return \WPDesk\AbstractShipping\Shipment\Weight
	 */
	protected function get_weight( $package_item ) {
		$weight              = new Weight();
		$weight->weight      = floatval( $package_item['data']->get_weight() );
		$weight->weight_unit = $this->get_woocommerce_weight_unit();

		return $weight;
	}

	/**
	 * Get item name.
	 *
	 * @param \WC_Product $package_item_data .
	 *
	 * @return string
	 */
	private function get_item_name( $package_item_data ) {
		return $package_item_data->get_name();
	}

	/**
	 * Add package items.
	 *
	 * @param array $package_item Package item.
	 *
	 * @return Item
	 */
	protected function add_package_item( $package_item ) {
		$item                           = new Item();
		$item->name                     = $this->get_item_name( $package_item['data'] );
		$item->dimensions               = $this->get_dimensions( $package_item );
		$item->weight                   = $this->get_weight( $package_item );
		$item->declared_value           = new Money();
		$item->declared_value->amount   = round( $package_item['line_total'] / $package_item['quantity'],
			$this->rounding_precision );
		$item->declared_value->currency = $this->currency;

		return $item;
	}

	/**
	 * Get dimension.
	 *
	 * @param array $package_item Package item.
	 *
	 * @return \WPDesk\AbstractShipping\Shipment\Dimensions
	 */
	protected function get_dimensions( $package_item ) {
		$dimension                  = new Dimensions();
		$dimension->dimensions_unit = $this->get_woocommerce_dimension_unit();
		$dimension->length          = $package_item['data']->get_length();
		$dimension->width           = $package_item['data']->get_width();
		$dimension->height          = $package_item['data']->get_height();

		return $dimension;
	}

	/**
	 * Get package.
	 *
	 * @return Package[]
	 */
	protected function get_packages() {
		$shipping_package = new Package();
		$shipping_package->items = [];
		$package_weight = new Weight();
		$package_weight->weight_unit = $this->get_woocommerce_weight_unit();
		$package_weight->weight = 0.0;
		foreach ( $this->package['contents'] as $item ) {
			for ( $i = 0; $i < $item['quantity']; $i ++ ) {
				$shipping_item = $this->add_package_item( $item );
				$package_weight->weight += $shipping_item->weight->weight;
				$shipping_package->items[] = $shipping_item;
			}
		}

		$shipping_package->weight = $package_weight;
		return [ $shipping_package ];
	}

	/**
	 * Return shipping. To work correctly you have set all the required elements trough setters.
	 *
	 * @return \WPDesk\AbstractShipping\Shipment\Shipment;
	 */
	public function build_shipment() {
		$shipment = new Shipment();

		$ship_from          = new Client();
		$ship_from->address = $this->sender_address->get_address();

		$ship_to          = new Client();
		$ship_to->address = $this->receiver_address->get_address();

		$shipment->ship_from = $ship_from;
		$shipment->ship_to   = $ship_to;
		$shipment->packages  = $this->get_packages();

		return $shipment;
	}
}

$packages = WC()->cart->get_shipping_packages();

foreach ( $packeges as $package ) {
	$shipping_builder = new WooCommerceShippingBuilder();
	$shipping_builder->set_woocommerce_package( $package );
	print_r( $shiping_builder->build_shipment() );
}