208 lines
6.4 KiB
PHP
208 lines
6.4 KiB
PHP
<?php
|
||
/**
|
||
* Shop address book service.
|
||
*
|
||
* Extracted from AKSRT_Shop to isolate user address-book CRUD
|
||
* (user_meta['aksrt_shop_addresses']) into a cohesive unit.
|
||
*
|
||
* @package AKSRT
|
||
*/
|
||
|
||
defined('ABSPATH') || exit;
|
||
|
||
class AKSRT_Shop_Address_Service {
|
||
|
||
private AKSRT_Shop $shop;
|
||
|
||
public function __construct(AKSRT_Shop $shop) {
|
||
$this->shop = $shop;
|
||
}
|
||
|
||
/**
|
||
* 获取用户地址簿(公开接口)
|
||
*/
|
||
public function get_address_book(int $user_id): array {
|
||
return $this->get_user_address_book($user_id);
|
||
}
|
||
|
||
public function get_user_address_book(int $user_id): array {
|
||
$saved = get_user_meta($user_id, 'aksrt_shop_addresses', true);
|
||
if (is_array($saved) && !empty($saved)) {
|
||
return array_values(array_filter(array_map([$this, 'sanitize_address'], $saved)));
|
||
}
|
||
|
||
return [];
|
||
}
|
||
|
||
private function sanitize_address($address): array {
|
||
if (!is_array($address)) {
|
||
return [];
|
||
}
|
||
|
||
$name = sanitize_text_field((string) ($address['name'] ?? ''));
|
||
$phone = sanitize_text_field((string) ($address['phone'] ?? ''));
|
||
$province = sanitize_text_field((string) ($address['province'] ?? ''));
|
||
$city = sanitize_text_field((string) ($address['city'] ?? ''));
|
||
$district = sanitize_text_field((string) ($address['district'] ?? ''));
|
||
$street = sanitize_text_field((string) ($address['address'] ?? ''));
|
||
|
||
return [
|
||
'id' => (int) ($address['id'] ?? 0),
|
||
'name' => $name,
|
||
'phone' => $phone,
|
||
'province' => $province,
|
||
'city' => $city,
|
||
'district' => $district,
|
||
'address' => $street,
|
||
'is_default' => !empty($address['is_default']),
|
||
'full_text' => trim($name . ' / ' . $province . $city . $district . $street),
|
||
];
|
||
}
|
||
|
||
/**
|
||
* 新增地址
|
||
*
|
||
* @param int $user_id
|
||
* @param array $data 地址数据(name, phone, province, city, district, address, is_default)
|
||
* @return array{success:bool, address:array|null, error:string|null}
|
||
*/
|
||
public function add_address(int $user_id, array $data): array {
|
||
$address = $this->sanitize_address($data);
|
||
if ($address['name'] === '' || $address['phone'] === '' || $address['address'] === '') {
|
||
return ['success' => false, 'address' => null, 'error' => __('姓名、手机号和详细地址为必填项。', 'aksrt')];
|
||
}
|
||
|
||
$book = $this->get_user_address_book($user_id);
|
||
$address['id'] = $this->next_address_id($book);
|
||
|
||
if (!empty($data['is_default']) || empty($book)) {
|
||
foreach ($book as &$item) {
|
||
$item['is_default'] = false;
|
||
}
|
||
$address['is_default'] = true;
|
||
}
|
||
|
||
$book[] = $address;
|
||
update_user_meta($user_id, 'aksrt_shop_addresses', $book);
|
||
|
||
return ['success' => true, 'address' => $address, 'error' => null];
|
||
}
|
||
|
||
/**
|
||
* 更新地址
|
||
*
|
||
* @param int $user_id
|
||
* @param int $address_id
|
||
* @param array $data
|
||
* @return array{success:bool, address:array|null, error:string|null}
|
||
*/
|
||
public function update_address(int $user_id, int $address_id, array $data): array {
|
||
$book = $this->get_user_address_book($user_id);
|
||
$found = false;
|
||
|
||
foreach ($book as &$item) {
|
||
if ((int) ($item['id'] ?? 0) !== $address_id) {
|
||
continue;
|
||
}
|
||
$found = true;
|
||
$merged = array_merge($item, $this->sanitize_address(array_merge($item, $data)));
|
||
$merged['id'] = $address_id;
|
||
|
||
if ($merged['name'] === '' || $merged['phone'] === '' || $merged['address'] === '') {
|
||
return ['success' => false, 'address' => null, 'error' => __('姓名、手机号和详细地址为必填项。', 'aksrt')];
|
||
}
|
||
|
||
if (!empty($data['is_default'])) {
|
||
foreach ($book as &$clear) {
|
||
$clear['is_default'] = false;
|
||
}
|
||
$merged['is_default'] = true;
|
||
}
|
||
|
||
$item = $merged;
|
||
break;
|
||
}
|
||
|
||
if (!$found) {
|
||
return ['success' => false, 'address' => null, 'error' => __('地址不存在。', 'aksrt')];
|
||
}
|
||
|
||
update_user_meta($user_id, 'aksrt_shop_addresses', $book);
|
||
|
||
return ['success' => true, 'address' => $merged, 'error' => null];
|
||
}
|
||
|
||
/**
|
||
* 删除地址
|
||
*
|
||
* @param int $user_id
|
||
* @param int $address_id
|
||
* @return array{success:bool, error:string|null}
|
||
*/
|
||
public function delete_address(int $user_id, int $address_id): array {
|
||
$book = $this->get_user_address_book($user_id);
|
||
$found = false;
|
||
$was_default = false;
|
||
$filtered = [];
|
||
|
||
foreach ($book as $item) {
|
||
if ((int) ($item['id'] ?? 0) === $address_id) {
|
||
$found = true;
|
||
$was_default = !empty($item['is_default']);
|
||
continue;
|
||
}
|
||
$filtered[] = $item;
|
||
}
|
||
|
||
if (!$found) {
|
||
return ['success' => false, 'error' => __('地址不存在。', 'aksrt')];
|
||
}
|
||
|
||
if ($was_default && !empty($filtered)) {
|
||
$filtered[0]['is_default'] = true;
|
||
}
|
||
|
||
update_user_meta($user_id, 'aksrt_shop_addresses', array_values($filtered));
|
||
|
||
return ['success' => true, 'error' => null];
|
||
}
|
||
|
||
/**
|
||
* 设置默认地址
|
||
*
|
||
* @param int $user_id
|
||
* @param int $address_id
|
||
* @return array{success:bool, error:string|null}
|
||
*/
|
||
public function set_default_address(int $user_id, int $address_id): array {
|
||
$book = $this->get_user_address_book($user_id);
|
||
$found = false;
|
||
|
||
foreach ($book as &$item) {
|
||
$item['is_default'] = ((int) ($item['id'] ?? 0) === $address_id);
|
||
if ($item['is_default']) {
|
||
$found = true;
|
||
}
|
||
}
|
||
|
||
if (!$found) {
|
||
return ['success' => false, 'error' => __('地址不存在。', 'aksrt')];
|
||
}
|
||
|
||
update_user_meta($user_id, 'aksrt_shop_addresses', $book);
|
||
|
||
return ['success' => true, 'error' => null];
|
||
}
|
||
|
||
/**
|
||
* 生成下一个地址 ID
|
||
*/
|
||
private function next_address_id(array $book): int {
|
||
$max = 0;
|
||
foreach ($book as $item) {
|
||
$max = max($max, (int) ($item['id'] ?? 0));
|
||
}
|
||
return $max + 1;
|
||
}
|
||
}
|