<?php
/**
* The purchase unit object.
*
* @package WooCommerce\PayPalCommerce\ApiClient\Entity
*/
declare (strict_types=1);
namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
use WooCommerce\PayPalCommerce\ApiClient\Helper\PurchaseUnitSanitizer;
/**
* Class PurchaseUnit
*/
class PurchaseUnit
{
/**
* The amount.
*
* @var Amount
*/
private $amount;
/**
* The Items.
*
* @var Item[]
*/
private $items;
/**
* The shipping.
*
* @var Shipping|null
*/
private $shipping;
/**
* The reference id.
*
* @var string
*/
private $reference_id;
/**
* The description.
*
* @var string
*/
private $description;
/**
* The custom id.
*
* @var string
*/
private $custom_id;
/**
* The invoice id.
*
* @var string
*/
private $invoice_id;
/**
* The soft descriptor.
*
* @var string
*/
private $soft_descriptor;
/**
* The Payments.
*
* @var Payments|null
*/
private $payments;
/**
* The supplementary data (Level 2/3 card processing).
*
* @var array|null
*/
private $supplementary_data;
/**
* Whether the unit contains physical goods.
*
* @var bool
*/
private $contains_physical_goods = \false;
/**
* The sanitizer for this purchase unit output.
*
* @var PurchaseUnitSanitizer|null
*/
private $sanitizer;
/**
* PurchaseUnit constructor.
*
* @param Amount $amount The Amount.
* @param Item[] $items The Items.
* @param Shipping|null $shipping The Shipping.
* @param string $reference_id The reference ID.
* @param string $description The description.
* @param string $custom_id The custom ID.
* @param string $invoice_id The invoice ID.
* @param string $soft_descriptor The soft descriptor.
* @param Payments|null $payments The Payments.
*/
public function __construct(\WooCommerce\PayPalCommerce\ApiClient\Entity\Amount $amount, array $items = array(), ?\WooCommerce\PayPalCommerce\ApiClient\Entity\Shipping $shipping = null, string $reference_id = 'default', string $description = '', string $custom_id = '', string $invoice_id = '', string $soft_descriptor = '', ?\WooCommerce\PayPalCommerce\ApiClient\Entity\Payments $payments = null, ?array $supplementary_data = null)
{
$this->amount = $amount;
$this->shipping = $shipping;
$this->reference_id = $reference_id;
$this->description = $description;
//phpcs:disable Inpsyde.CodeQuality.ArgumentTypeDeclaration.NoArgumentType
$this->items = array_values(array_filter($items, function ($item): bool {
$is_item = $item instanceof \WooCommerce\PayPalCommerce\ApiClient\Entity\Item;
// @phpstan-ignore instanceof.alwaysTrue
if ($is_item && \WooCommerce\PayPalCommerce\ApiClient\Entity\Item::PHYSICAL_GOODS === $item->category()) {
// @phpstan-ignore booleanAnd.leftAlwaysTrue
$this->contains_physical_goods = \true;
}
return $is_item;
}));
$this->custom_id = $custom_id;
$this->invoice_id = $invoice_id;
$this->soft_descriptor = $soft_descriptor;
$this->payments = $payments;
$this->supplementary_data = $supplementary_data;
}
/**
* Returns the amount.
*
* @return Amount
*/
public function amount(): \WooCommerce\PayPalCommerce\ApiClient\Entity\Amount
{
return $this->amount;
}
/**
* Sets the amount.
*
* @param Amount $amount The value to set.
*/
public function set_amount(\WooCommerce\PayPalCommerce\ApiClient\Entity\Amount $amount): void
{
$this->amount = $amount;
}
/**
* Returns the shipping.
*
* @return Shipping|null
*/
public function shipping()
{
return $this->shipping;
}
/**
* Sets shipping info.
*
* @param Shipping|null $shipping The value to set.
*/
public function set_shipping(?\WooCommerce\PayPalCommerce\ApiClient\Entity\Shipping $shipping): void
{
$this->shipping = $shipping;
}
/**
* Returns the reference id.
*
* @return string
*/
public function reference_id(): string
{
return $this->reference_id;
}
/**
* Returns the description.
*
* @return string
*/
public function description(): string
{
return $this->description;
}
/**
* Returns the custom id.
*
* @return string
*/
public function custom_id(): string
{
return $this->custom_id;
}
/**
* Sets the custom ID.
*
* @param string $custom_id The value to set.
*/
public function set_custom_id(string $custom_id): void
{
$this->custom_id = $custom_id;
}
/**
* Sets the sanitizer for this purchase unit output.
*
* @param PurchaseUnitSanitizer|null $sanitizer The sanitizer.
* @return void
*/
public function set_sanitizer(?PurchaseUnitSanitizer $sanitizer)
{
$this->sanitizer = $sanitizer;
}
/**
* Returns the invoice id.
*
* @return string
*/
public function invoice_id(): string
{
return $this->invoice_id;
}
/**
* Returns the soft descriptor.
*
* @return string
*/
public function soft_descriptor(): string
{
return $this->soft_descriptor;
}
/**
* Returns the Payments.
*
* @return Payments|null
*/
public function payments()
{
return $this->payments;
}
/**
* Returns the supplementary data.
*
* @return array|null
*/
public function supplementary_data(): ?array
{
return $this->supplementary_data;
}
/**
* Returns the Items.
*
* @return Item[]
*/
public function items(): array
{
return $this->items;
}
/**
* Whether the unit contains physical goods.
*
* @return bool
*/
public function contains_physical_goods(): bool
{
return $this->contains_physical_goods;
}
/**
* Returns the object as array.
*
* @param bool $sanitize_output Whether output should be sanitized for PayPal consumption.
* @param bool $allow_ditch_items Whether to allow items to be ditched.
*
* @return array
*/
public function to_array(bool $sanitize_output = \true, bool $allow_ditch_items = \true): array
{
$purchase_unit = array('reference_id' => $this->reference_id(), 'amount' => $this->amount()->to_array(), 'description' => $this->description(), 'items' => array_map(static function (\WooCommerce\PayPalCommerce\ApiClient\Entity\Item $item): array {
return $item->to_array();
}, $this->items()));
if ($this->payments()) {
$purchase_unit['payments'] = $this->payments()->to_array();
}
if ($this->shipping()) {
$purchase_unit['shipping'] = $this->shipping()->to_array();
}
if ($this->custom_id()) {
$purchase_unit['custom_id'] = $this->custom_id();
}
if ($this->invoice_id()) {
$purchase_unit['invoice_id'] = $this->invoice_id();
}
if ($this->soft_descriptor()) {
$purchase_unit['soft_descriptor'] = $this->soft_descriptor();
}
if ($this->supplementary_data()) {
$purchase_unit['supplementary_data'] = $this->supplementary_data();
}
$has_ditched_items_breakdown = \false;
if ($sanitize_output && isset($this->sanitizer)) {
$purchase_unit = $this->sanitizer->sanitize($purchase_unit, $allow_ditch_items);
$has_ditched_items_breakdown = $this->sanitizer->has_ditched_items_breakdown();
}
return $this->apply_ditch_items_mismatch_filter($has_ditched_items_breakdown, $purchase_unit);
}
/**
* Applies the ppcp_ditch_items_breakdown filter.
* If true purchase_unit items and breakdown are ditched from PayPal.
*
* @param bool $ditched_items_breakdown If the breakdown and items were already ditched.
* @param array $purchase_unit The purchase_unit array.
* @return array
*/
public function apply_ditch_items_mismatch_filter(bool $ditched_items_breakdown, array $purchase_unit): array
{
/**
* The filter can be used to control when the items and totals breakdown are removed from PayPal order info.
*/
$ditch = apply_filters('ppcp_ditch_items_breakdown', $ditched_items_breakdown, $this);
if ($ditch) {
unset($purchase_unit['items']);
unset($purchase_unit['amount']['breakdown']);
if (isset($this->sanitizer) && $ditch !== $ditched_items_breakdown) {
$this->sanitizer->set_last_message(__('Ditch items breakdown filter. Items and breakdown ditched.', 'woocommerce-paypal-payments'));
}
}
return $purchase_unit;
}
}