feat(orders): redesign user order center
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
/**
|
||||
* Canonical query state for the knowledge-payment order center.
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
namespace AKSRT\Payment;
|
||||
|
||||
use AKSRT\Core\DomainModel;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
final class OrderCenterQuery {
|
||||
|
||||
public const STATUS_ALL = 'all';
|
||||
public const STATUS_PENDING = 'pending';
|
||||
public const STATUS_COMPLETED = 'completed';
|
||||
public const STATUS_CLOSED = 'closed';
|
||||
|
||||
private const STATUS_GROUPS = [
|
||||
self::STATUS_ALL,
|
||||
self::STATUS_PENDING,
|
||||
self::STATUS_COMPLETED,
|
||||
self::STATUS_CLOSED,
|
||||
];
|
||||
|
||||
/** @var array<string, mixed> */
|
||||
private array $values;
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $values
|
||||
*/
|
||||
private function __construct(array $values) {
|
||||
$this->values = $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $raw
|
||||
*/
|
||||
public static function from_array(array $raw, int $default_per_page = 20): self {
|
||||
$status = sanitize_key((string) ($raw['status'] ?? self::STATUS_ALL));
|
||||
if (!in_array($status, self::STATUS_GROUPS, true)) {
|
||||
$status = self::STATUS_ALL;
|
||||
}
|
||||
|
||||
$product_type = sanitize_key((string) ($raw['type'] ?? $raw['product_type'] ?? ''));
|
||||
$types = DomainModel::order_product_type_labels();
|
||||
if ($product_type !== '' && !isset($types[$product_type])) {
|
||||
$product_type = '';
|
||||
}
|
||||
|
||||
$order_number = strtoupper(preg_replace('/[^A-Za-z0-9_-]/', '', (string) ($raw['order_number'] ?? '')) ?? '');
|
||||
$order_number = substr($order_number, 0, 32);
|
||||
|
||||
$page = max(1, absint($raw['page'] ?? 1));
|
||||
$per_page = max(1, min(50, absint($raw['per_page'] ?? $default_per_page)));
|
||||
|
||||
return new self([
|
||||
'status' => $status,
|
||||
'product_type' => $product_type,
|
||||
'order_number' => $order_number,
|
||||
'page' => $page,
|
||||
'per_page' => $per_page,
|
||||
]);
|
||||
}
|
||||
|
||||
public function status(): string {
|
||||
return (string) $this->values['status'];
|
||||
}
|
||||
|
||||
public function product_type(): string {
|
||||
return (string) $this->values['product_type'];
|
||||
}
|
||||
|
||||
public function order_number(): string {
|
||||
return (string) $this->values['order_number'];
|
||||
}
|
||||
|
||||
public function page(): int {
|
||||
return (int) $this->values['page'];
|
||||
}
|
||||
|
||||
public function per_page(): int {
|
||||
return (int) $this->values['per_page'];
|
||||
}
|
||||
|
||||
/** @return string[] */
|
||||
public function database_statuses(): array {
|
||||
return match ($this->status()) {
|
||||
self::STATUS_PENDING => [Order::STATUS_CREATED, Order::STATUS_PENDING],
|
||||
self::STATUS_COMPLETED => [Order::STATUS_PAID],
|
||||
self::STATUS_CLOSED => [Order::STATUS_CANCELLED, Order::STATUS_EXPIRED],
|
||||
default => [
|
||||
Order::STATUS_CREATED,
|
||||
Order::STATUS_PENDING,
|
||||
Order::STATUS_PAID,
|
||||
Order::STATUS_CANCELLED,
|
||||
Order::STATUS_EXPIRED,
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
/** @return array<string, scalar> */
|
||||
public function url_values(): array {
|
||||
return array_filter([
|
||||
'order_status' => $this->status() !== self::STATUS_ALL ? $this->status() : '',
|
||||
'order_type' => $this->product_type(),
|
||||
'order_number' => $this->order_number(),
|
||||
'order_page' => $this->page() > 1 ? $this->page() : '',
|
||||
], static fn($value): bool => $value !== '');
|
||||
}
|
||||
|
||||
/** @return array<string, mixed> */
|
||||
public function repository_args(): array {
|
||||
return [
|
||||
'status_in' => $this->database_statuses(),
|
||||
'product_type' => $this->product_type(),
|
||||
'order_number_prefix' => $this->order_number(),
|
||||
'limit' => $this->per_page(),
|
||||
'offset' => ($this->page() - 1) * $this->per_page(),
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user