|
|
<?php
|
|
|
|
|
|
namespace App\Support;
|
|
|
|
|
|
use App\Models\Application;
|
|
|
use App\Models\AudienceRegistration;
|
|
|
use App\Models\AudienceSession;
|
|
|
use App\Models\Competition;
|
|
|
use App\Models\CompetitionTrack;
|
|
|
|
|
|
final class SignupDisplay
|
|
|
{
|
|
|
public const TRACK_OTHER_CODE = 'other';
|
|
|
|
|
|
public const TRACK_OTHER_FIELD = 'track_other';
|
|
|
|
|
|
public static function applicationLocale(Application $app): string
|
|
|
{
|
|
|
return PortalLocale::isValid((string) $app->signup_locale)
|
|
|
? (string) $app->signup_locale
|
|
|
: PortalLocale::ZH;
|
|
|
}
|
|
|
|
|
|
public static function localeTag(string $locale): string
|
|
|
{
|
|
|
return $locale === PortalLocale::EN ? '英文填报' : '中文填报';
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @param list<mixed>|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<mixed>|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 formatLocation(Application $app): string
|
|
|
{
|
|
|
$locale = self::applicationLocale($app);
|
|
|
$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;
|
|
|
}
|
|
|
}
|