Use Composer modules and convert modules to PSR-4

PSR-4 is much more robust and predictable. But to do this,
a source root dir must be specified for every module.
This could be done in the root file, but this is not very modular.
Instead, now every module declares its own source root by using
the amazing Composer Merge Plugin. This approach allows each module
to also declare its own dependencies. Together, these changes allow
modules to be easily extractable to separate pacakges when the need
arises, and in general improves modularity significantly.
This commit is contained in:
Anton Ukhanev 2021-02-17 12:31:40 +01:00
parent 45db097bd8
commit d4c8282518
157 changed files with 168 additions and 8 deletions

View file

@ -0,0 +1,200 @@
<?php
/**
* The Item factory.
*
* @package WooCommerce\PayPalCommerce\ApiClient\Factory
*/
declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
use WooCommerce\PayPalCommerce\ApiClient\Entity\Item;
use WooCommerce\PayPalCommerce\ApiClient\Entity\Money;
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
/**
* Class ItemFactory
*/
class ItemFactory {
/**
* Creates items based off a WooCommerce cart.
*
* @param \WC_Cart $cart The cart.
*
* @return Item[]
*/
public function from_wc_cart( \WC_Cart $cart ): array {
$currency = get_woocommerce_currency();
$items = array_map(
static function ( array $item ) use ( $currency ): Item {
$product = $item['data'];
/**
* The WooCommerce product.
*
* @var \WC_Product $product
*/
$quantity = (int) $item['quantity'];
$price = (float) wc_get_price_including_tax( $product );
$price_without_tax = (float) wc_get_price_excluding_tax( $product );
$price_without_tax_rounded = round( $price_without_tax, 2 );
$tax = round( $price - $price_without_tax_rounded, 2 );
$tax = new Money( $tax, $currency );
return new Item(
mb_substr( $product->get_name(), 0, 127 ),
new Money( $price_without_tax_rounded, $currency ),
$quantity,
mb_substr( wp_strip_all_tags( $product->get_description() ), 0, 127 ),
$tax,
$product->get_sku(),
( $product->is_virtual() ) ? Item::DIGITAL_GOODS : Item::PHYSICAL_GOODS
);
},
$cart->get_cart_contents()
);
$fees = array();
$fees_from_session = WC()->session->get( 'ppcp_fees' );
if ( $fees_from_session ) {
$fees = array_map(
static function ( \stdClass $fee ) use ( $currency ): Item {
return new Item(
$fee->name,
new Money( (float) $fee->amount, $currency ),
1,
'',
new Money( (float) $fee->tax, $currency )
);
},
$fees_from_session
);
}
return array_merge( $items, $fees );
}
/**
* Creates Items based off a WooCommerce order.
*
* @param \WC_Order $order The order.
* @return Item[]
*/
public function from_wc_order( \WC_Order $order ): array {
$items = array_map(
function ( \WC_Order_Item_Product $item ) use ( $order ): Item {
return $this->from_wc_order_line_item( $item, $order );
},
$order->get_items( 'line_item' )
);
$fees = array_map(
function ( \WC_Order_Item_Fee $item ) use ( $order ): Item {
return $this->from_wc_order_fee( $item, $order );
},
$order->get_fees()
);
return array_merge( $items, $fees );
}
/**
* Creates an Item based off a WooCommerce Order Item.
*
* @param \WC_Order_Item_Product $item The WooCommerce order item.
* @param \WC_Order $order The WooCommerce order.
*
* @return Item
*/
private function from_wc_order_line_item( \WC_Order_Item_Product $item, \WC_Order $order ): Item {
$currency = $order->get_currency();
$product = $item->get_product();
/**
* The WooCommerce product.
*
* @var \WC_Product $product
*/
$quantity = (int) $item->get_quantity();
$price = (float) $order->get_item_subtotal( $item, true );
$price_without_tax = (float) $order->get_item_subtotal( $item, false );
$price_without_tax_rounded = round( $price_without_tax, 2 );
$tax = round( $price - $price_without_tax_rounded, 2 );
$tax = new Money( $tax, $currency );
return new Item(
mb_substr( $product->get_name(), 0, 127 ),
new Money( $price_without_tax_rounded, $currency ),
$quantity,
mb_substr( wp_strip_all_tags( $product->get_description() ), 0, 127 ),
$tax,
$product->get_sku(),
( $product->is_virtual() ) ? Item::DIGITAL_GOODS : Item::PHYSICAL_GOODS
);
}
/**
* Creates an Item based off a WooCommerce Fee Item.
*
* @param \WC_Order_Item_Fee $item The WooCommerce order item.
* @param \WC_Order $order The WooCommerce order.
*
* @return Item
*/
private function from_wc_order_fee( \WC_Order_Item_Fee $item, \WC_Order $order ): Item {
return new Item(
$item->get_name(),
new Money( (float) $item->get_amount(), $order->get_currency() ),
$item->get_quantity(),
'',
new Money( (float) $item->get_total_tax(), $order->get_currency() )
);
}
/**
* Creates an Item based off a PayPal response.
*
* @param \stdClass $data The JSON object.
*
* @return Item
* @throws RuntimeException When JSON object is malformed.
*/
public function from_paypal_response( \stdClass $data ): Item {
if ( ! isset( $data->name ) ) {
throw new RuntimeException(
__( 'No name for item given', 'woocommerce-paypal-payments' )
);
}
if ( ! isset( $data->quantity ) || ! is_numeric( $data->quantity ) ) {
throw new RuntimeException(
__( 'No quantity for item given', 'woocommerce-paypal-payments' )
);
}
if ( ! isset( $data->unit_amount->value ) || ! isset( $data->unit_amount->currency_code ) ) {
throw new RuntimeException(
__( 'No money values for item given', 'woocommerce-paypal-payments' )
);
}
$unit_amount = new Money( (float) $data->unit_amount->value, $data->unit_amount->currency_code );
$description = ( isset( $data->description ) ) ? $data->description : '';
$tax = ( isset( $data->tax ) ) ?
new Money( (float) $data->tax->value, $data->tax->currency_code )
: null;
$sku = ( isset( $data->sku ) ) ? $data->sku : '';
$category = ( isset( $data->category ) ) ? $data->category : 'PHYSICAL_GOODS';
return new Item(
$data->name,
$unit_amount,
(int) $data->quantity,
$description,
$tax,
$sku,
$category
);
}
}