applications = $applications ?? new ApplicationRepository(); $this->evidence = $evidence ?? new EvidenceService(); } /** @return array|\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 */ 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; } }