112 lines
4.3 KiB
PHP
112 lines
4.3 KiB
PHP
<?php
|
|
/** Manual identity application flow. @package AKSRT */
|
|
|
|
namespace AKSRT\Identity;
|
|
|
|
defined('ABSPATH') || exit;
|
|
|
|
final class ApplicationService {
|
|
|
|
private ApplicationRepository $applications;
|
|
private EvidenceService $evidence;
|
|
|
|
public function __construct(?ApplicationRepository $applications = null, ?EvidenceService $evidence = null) {
|
|
$this->applications = $applications ?? new ApplicationRepository();
|
|
$this->evidence = $evidence ?? new EvidenceService();
|
|
}
|
|
|
|
/** @return array<string,mixed>|\WP_Error */
|
|
public function create(int $user_id, array $input, $files = null) {
|
|
$settings = \AKSRT\User\AuthApply::settings();
|
|
if (empty($settings['enabled']) || empty($settings['allow_apply'])) {
|
|
return new \WP_Error('aksrt_identity_disabled', __('暂不能申请身份认证', 'aksrt'), ['status' => 403]);
|
|
}
|
|
if (\AKSRT\User\AuthApply::is_verified($user_id)) {
|
|
return new \WP_Error('aksrt_identity_verified', __('您已是认证用户', 'aksrt'), ['status' => 409]);
|
|
}
|
|
if ($this->applications->active_for_user($user_id)) {
|
|
return new \WP_Error('aksrt_identity_active', __('您的申请已提交,请耐心等待', 'aksrt'), ['status' => 409]);
|
|
}
|
|
$minimum_level = max(0, (int) ($settings['minimum_level'] ?? 0));
|
|
$identity_settings = class_exists('AKSRT\\Settings\\Settings')
|
|
? \AKSRT\Settings\Settings::get_user_identity_settings()
|
|
: [];
|
|
$level_enabled = !isset($identity_settings['level']['enabled']) || !empty($identity_settings['level']['enabled']);
|
|
if (!\AKSRT\User\AuthApply::meets_minimum_level($user_id, $minimum_level, $level_enabled)) {
|
|
return new \WP_Error('aksrt_identity_level', __('当前等级暂不能申请身份认证', 'aksrt'), ['status' => 403]);
|
|
}
|
|
|
|
$name = sanitize_text_field((string) ($input['name'] ?? ''));
|
|
$description = sanitize_textarea_field((string) ($input['description'] ?? ''));
|
|
$message = sanitize_textarea_field((string) ($input['message'] ?? ''));
|
|
if ($this->length($name) < 4 || $this->length($name) > 16) {
|
|
return new \WP_Error('aksrt_identity_name', __('认证名称不能少于 4 个或超过 16 个字符', 'aksrt'));
|
|
}
|
|
|
|
$uuid = wp_generate_uuid4();
|
|
$evidence_ids = [];
|
|
if ($files !== null) {
|
|
$evidence_ids = $this->evidence->upload($user_id, $uuid, $files);
|
|
if (is_wp_error($evidence_ids)) {
|
|
return $evidence_ids;
|
|
}
|
|
}
|
|
$created = $this->applications->create([
|
|
'application_uuid' => $uuid,
|
|
'client_request_id' => wp_generate_uuid4(),
|
|
'request_payload_hash' => hash('sha256', wp_json_encode([$name, $description, $message])),
|
|
'user_id' => $user_id,
|
|
'type' => 'general',
|
|
'channel' => 'manual',
|
|
'status' => 'manual_pending',
|
|
'public_name' => $name,
|
|
'description' => $description,
|
|
'manual_reason' => $message,
|
|
'evidence_ids' => wp_json_encode(array_map('absint', $evidence_ids)),
|
|
]);
|
|
if (is_wp_error($created)) {
|
|
$this->evidence->delete($evidence_ids);
|
|
return $created;
|
|
}
|
|
(new EventRepository())->record([
|
|
'application_id' => (int) $created['id'],
|
|
'source' => 'user',
|
|
'event_type' => 'application_submitted',
|
|
'dedupe_key' => hash('sha256', $uuid . '|submitted'),
|
|
'to_status' => 'manual_pending',
|
|
'actor_user_id' => $user_id,
|
|
'summary' => ['name' => $name],
|
|
]);
|
|
if (class_exists('AKSRT\\Settings\\MailNotifications')) {
|
|
\AKSRT\Settings\MailNotifications::auth_submitted($user_id, $created);
|
|
}
|
|
return $this->view($created);
|
|
}
|
|
|
|
/** @return array<string,mixed> */
|
|
private function view(array $application): array {
|
|
$items = [];
|
|
foreach ($this->evidence->items($application) as $item) {
|
|
$items[] = ['url' => $item['url'], 'thumbnail_url' => $item['thumbnail_url']];
|
|
}
|
|
return [
|
|
'uuid' => (string) ($application['application_uuid'] ?? ''),
|
|
'status' => TransitionService::public_status((string) ($application['status'] ?? '')),
|
|
'name' => (string) ($application['public_name'] ?? ''),
|
|
'description' => (string) ($application['description'] ?? ''),
|
|
'message' => (string) ($application['manual_reason'] ?? ''),
|
|
'admin_note' => (string) ($application['review_note'] ?? ''),
|
|
'time' => (string) ($application['created_at'] ?? ''),
|
|
'evidence' => $items,
|
|
];
|
|
}
|
|
|
|
private function length(string $value): int {
|
|
if (function_exists('mb_strlen')) {
|
|
return mb_strlen($value);
|
|
}
|
|
$count = preg_match_all('/./us', $value, $matches);
|
|
return $count === false ? strlen($value) : $count;
|
|
}
|
|
}
|