signup_locale) ? (string) $app->signup_locale : PortalLocale::ZH; } public static function localeTag(string $locale): string { return $locale === PortalLocale::EN ? '英文填报' : '中文填报'; } /** * @param list|null $schemaJson */ public static function applicationFieldValue(Application $app, string $key): mixed { if ($key === 'track') { return $app->track; } $columns = array_flip(SignupApplicationFieldRegistry::scalarColumnKeys()); if (isset($columns[$key])) { return $app->{$key}; } $answers = is_array($app->answers_json) ? $app->answers_json : []; return $answers[$key] ?? null; } /** * @param list|null $schemaJson */ public static function applicationFieldLabel( Competition $competition, Application $app, string $key, ?array $schemaJson = null, ): string { $locale = self::applicationLocale($app); $raw = self::applicationFieldValue($app, $key); $value = is_scalar($raw) ? trim((string) $raw) : ''; if ($value === '') { return ''; } if ($key === 'degree') { return SignupOptionCatalog::label(SignupOptionCatalog::degrees(), $value, $locale); } if ($key === 'location_country') { return SignupOptionCatalog::label(SignupOptionCatalog::locationCountries(), $value, $locale); } if ($key === 'event_location') { return SignupOptionCatalog::label(SignupOptionCatalog::eventLocations(), $value, $locale); } if ($key === 'track') { if ($value === self::TRACK_OTHER_CODE) { return $locale === PortalLocale::EN ? 'Other' : '其他'; } $competition->loadMissing('tracks'); /** @var CompetitionTrack|null $track */ $track = $competition->tracks->firstWhere('track_code', $value); if ($track === null) { return $value; } return $locale === PortalLocale::EN && filled($track->title_en) ? (string) $track->title_en : (string) $track->title; } $schema = $schemaJson ?? ($competition->formSchema?->schema_json ?? null); $field = LocalizedSchema::fieldByKey(is_array($schema) ? $schema : null, $key); if ($field !== null && ($field['type'] ?? '') === 'select') { return LocalizedSchema::optionLabelForValue($field, $value, $locale); } return $value; } public static function trackTitleForApplication(Competition $competition, Application $app): string { $base = self::applicationFieldLabel($competition, $app, 'track'); if ($base === '') { $base = trim((string) $app->track); } $note = trim((string) (self::applicationFieldValue($app, self::TRACK_OTHER_FIELD) ?? '')); if ($note !== '' && (string) $app->track === self::TRACK_OTHER_CODE) { return $base === '' ? $note : $base.'('.$note.')'; } return $base; } public static function catalogLabel(string $kind, ?string $raw, string $locale = PortalLocale::ZH): string { $value = trim((string) $raw); if ($value === '') { return ''; } $catalog = match ($kind) { 'degree' => SignupOptionCatalog::degrees(), 'location_country' => SignupOptionCatalog::locationCountries(), 'event_location' => SignupOptionCatalog::eventLocations(), 'purpose', 'audience_purpose' => SignupOptionCatalog::audiencePurposes(), default => null, }; if ($catalog === null) { return $value; } return SignupOptionCatalog::label($catalog, $value, $locale); } public static function formatLocation(Application $app, string $locale = PortalLocale::ZH): string { $country = SignupOptionCatalog::normalize('location_country', (string) $app->location_country); $countryLabel = $country !== null && $country !== '' ? SignupOptionCatalog::label(SignupOptionCatalog::locationCountries(), $country, $locale) : ''; if ($country === 'cn') { return implode(' / ', array_values(array_filter([ $countryLabel, trim((string) $app->location_province), trim((string) $app->location_city), ], fn ($v) => $v !== ''))); } if ($country === 'overseas') { return implode(' / ', array_values(array_filter([ $countryLabel, trim((string) $app->oversea_country), ], fn ($v) => $v !== ''))); } return $countryLabel; } public static function sessionName(AudienceSession $session, string $locale): string { return $locale === PortalLocale::EN && filled($session->name_en) ? (string) $session->name_en : (string) $session->name; } public static function sessionDateText(AudienceSession $session, string $locale): string { return $locale === PortalLocale::EN && filled($session->event_date_text_en) ? (string) $session->event_date_text_en : (string) $session->event_date_text; } public static function sessionAddress(AudienceSession $session, string $locale): string { return $locale === PortalLocale::EN && filled($session->address_en) ? (string) $session->address_en : (string) $session->address; } public static function purposeLabel(string $code, string $locale): string { return SignupOptionCatalog::label( SignupOptionCatalog::audiencePurposes(), SignupOptionCatalog::normalize('purpose', $code) ?? $code, $locale ); } public static function audienceLocale(int $userId, int $competitionId): string { $row = \App\Models\CompetitionPortalLocale::query() ->where('user_id', $userId) ->where('competition_id', $competitionId) ->where('portal', PortalLocale::PORTAL_AUDIENCE) ->first(); return $row && PortalLocale::isValid((string) $row->locale) ? (string) $row->locale : PortalLocale::ZH; } public static function audienceFieldValue(AudienceRegistration $row, string $key): mixed { if (in_array($key, ['name', 'phone', 'company', 'job', 'purpose'], true)) { return $row->{$key}; } $answers = is_array($row->answers_json) ? $row->answers_json : []; return $answers[$key] ?? null; } }