Files
wordpress-theme-aksrt/src/Identity/ApplicationService.php
T

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;
}
}