121 lines
3.6 KiB
PHP
121 lines
3.6 KiB
PHP
<?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_PAID = 'paid';
|
|
public const STATUS_REFUNDING = 'refunding';
|
|
public const STATUS_REFUNDED = 'refunded';
|
|
public const STATUS_CLOSED = 'closed';
|
|
|
|
private const STATUS_GROUPS = [
|
|
self::STATUS_ALL,
|
|
self::STATUS_PENDING,
|
|
self::STATUS_PAID,
|
|
self::STATUS_REFUNDING,
|
|
self::STATUS_REFUNDED,
|
|
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 {
|
|
if ($this->status() === self::STATUS_ALL) {
|
|
return array_keys(DomainModel::order_status_labels());
|
|
}
|
|
return [$this->status()];
|
|
}
|
|
|
|
/** @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(),
|
|
];
|
|
}
|
|
}
|