Skip to content

Doctype fixes for new PHPstan #3020

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions webapp/src/Controller/API/ProblemController.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public function __construct(
/**
* Add one or more problems.
*
* @return int[]
* @return string[]
* @throws BadRequestHttpException
* @throws NonUniqueResultException
*/
Expand Down Expand Up @@ -105,7 +105,7 @@ public function addProblemsAction(Request $request): array
$data = Yaml::parseFile($file->getRealPath(), Yaml::PARSE_DATETIME);
$messages = [];
if ($this->importExportService->importProblemsData($contest, $data, $ids, $messages)) {
return $ids;
return $ids ?? [];
}
$message = "Error while adding problems";
if (!empty($messages)) {
Expand Down
14 changes: 1 addition & 13 deletions webapp/src/Controller/Jury/RejudgingController.php
Original file line number Diff line number Diff line change
Expand Up @@ -788,20 +788,8 @@ public function createAction(Request $request): Response
} else {
$redirect = $this->generateUrl('jury_index');
}
} elseif ($res instanceof Rejudging) {
$redirect = $this->generateUrl('jury_rejudging', ['rejudgingId' => $res->getRejudgingid()]);
} else {
$redirect = match ($table) {
'contest' => $this->generateUrl('jury_contest', ['contestId' => $id]),
'judgehost' => $this->generateUrl('jury_judgehost', ['judgehostid' => $id]),
'language' => $this->generateUrl('jury_language', ['langId' => $id]),
'problem' => $this->generateUrl('jury_problem', ['probId' => $id]),
'submission' => $this->generateUrl('jury_submission', ['submitId' => $id]),
'team' => $this->generateUrl('jury_team', ['teamId' => $id]),
// This case never happens, since we already check above.
// Add it here to silence linter warnings.
default => throw new BadRequestHttpException(sprintf('unknown table %s in rejudging', $table)),
};
$redirect = $this->generateUrl('jury_rejudging', ['rejudgingId' => $res->getRejudgingid()]);
}

$progressReporter(100, '', $redirect);
Expand Down
2 changes: 1 addition & 1 deletion webapp/src/Controller/Team/SubmissionController.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public function createAction(Request $request, ?Problem $problem = null): Respon
$problem = $form->get('problem')->getData();
/** @var Language $language */
$language = $form->get('language')->getData();
/** @var UploadedFile[] $files */
/** @var UploadedFile[]|UploadedFile $files */
$files = $form->get('code')->getData();
if (!is_array($files)) {
$files = [$files];
Expand Down
2 changes: 1 addition & 1 deletion webapp/src/DataFixtures/DefaultData/UserFixture.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ protected function getRestapiPassword(): string
if ($credential === '' || $credential[0] === '#') {
continue;
}
/** @var string[] $items */
/** @var list<string> $items */
$items = preg_split("/\s+/", $credential);
if (count($items) !== 4) {
throw new Exception("Error parsing REST API credentials. Invalid format in line $lineno.");
Expand Down
2 changes: 1 addition & 1 deletion webapp/src/DataFixtures/Test/RejudgingStatesFixture.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public function load(ObjectManager $manager): void
$manager->flush();
// One rejudging can consist of submissions of multiple contests
foreach ($rejudgingStage[4] as $contestName) {
/** @var Contest $contest */
/** @var Contest|null $contest */
$contest = $manager->getRepository(Contest::class)->findOneBy(['shortname' => $contestName]);
/** @var Team $team */
$team = $manager->getRepository(Team::class)->findOneBy(['name' => 'Example teamname']);
Expand Down
9 changes: 6 additions & 3 deletions webapp/src/Doctrine/DBAL/Types/JsonType.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,13 @@ public function getSQLDeclaration(array $column, AbstractPlatform $platform): st
}

/**
* @return string|false|null
* @throws ConversionException
* @template T
* @param T $value
*
* @return (T is null ? null : string)
* @throws \JsonException
*/
public function convertToDatabaseValue($value, AbstractPlatform $platform)
public function convertToDatabaseValue($value, AbstractPlatform $platform): ?string
{
if ($value === null) {
return null;
Expand Down
2 changes: 1 addition & 1 deletion webapp/src/Entity/Testcase.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ class Testcase
private Collection $judging_runs;

/**
* @var Collection<int, ExternalRun>>
* @var Collection<int, ExternalRun>
*/
#[ORM\OneToMany(mappedBy: 'testcase', targetEntity: ExternalRun::class)]
#[Serializer\Exclude]
Expand Down
49 changes: 0 additions & 49 deletions webapp/src/Form/Type/ExecutableType.php

This file was deleted.

5 changes: 2 additions & 3 deletions webapp/src/FosRestBundle/FlattenExceptionHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public static function getSubscribingMethods(): array
}

/**
* @param array{params: string[]} $type
* @param array{name: string, params: string[]} $type
*
* @return array{code: int, message: string}
*/
Expand All @@ -49,8 +49,7 @@ public function serializeToJson(
array $type,
Context $context
): array {
return $visitor->visitArray($this->convertToArray($exception, $context),
$type);
return $visitor->visitArray($this->convertToArray($exception, $context), $type);
}

/**
Expand Down
3 changes: 1 addition & 2 deletions webapp/src/Security/DOMJudgeIPAuthenticator.php
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,7 @@ public function onAuthenticationSuccess(Request $request, TokenInterface $token,
&& $request->isMethod('POST')
&& $request->request->get('loginmethod') === 'ipaddress') {
// Use target URL from session if set.
if ($firewallName !== null &&
$targetUrl = $this->getTargetPath($request->getSession(), $firewallName)) {
if ($targetUrl = $this->getTargetPath($request->getSession(), $firewallName)) {
$this->removeTargetPath($request->getSession(), $firewallName);
return new RedirectResponse($targetUrl);
}
Expand Down
3 changes: 1 addition & 2 deletions webapp/src/Security/DOMJudgeXHeadersAuthenticator.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,7 @@ public function onAuthenticationSuccess(Request $request, TokenInterface $token,
&& $request->isMethod('POST')
&& $request->request->get('loginmethod') === 'xheaders') {
// Use target URL from session if set.
if ($firewallName !== null &&
$targetUrl = $this->getTargetPath($request->getSession(), $firewallName)) {
if ($targetUrl = $this->getTargetPath($request->getSession(), $firewallName)) {
$this->removeTargetPath($request->getSession(), $firewallName);
return new RedirectResponse($targetUrl);
}
Expand Down
2 changes: 1 addition & 1 deletion webapp/src/Serializer/Shadowing/EventDataDenormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public function denormalize(
}

/**
* @param array{api_version?: string, event_type?: EventType} $context
* @param array{api_version?: string, event_type?: mixed} $context
*/
public function supportsDenormalization(
mixed $data,
Expand Down
2 changes: 1 addition & 1 deletion webapp/src/Service/AssetUpdateService.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public function __construct(protected readonly DOMJudgeService $dj, protected re
/**
* Update assets for the given entity.
*/
public function updateAssets(AssetEntityInterface &$entity): void
public function updateAssets(AssetEntityInterface $entity): void
{
$fs = new Filesystem();

Expand Down
5 changes: 3 additions & 2 deletions webapp/src/Service/ConfigurationService.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ public function all(bool $onlyIfPublic = false): array
/**
* Get all configuration specifications.
*
* @return ConfigurationSpecification[]
* @return array<string, ConfigurationSpecification>
*/
public function getConfigSpecification(): array
{
Expand Down Expand Up @@ -160,6 +160,7 @@ function (ConfigCacheInterface $cache) {
*
* @throws NonUniqueResultException
* @param array<string, Configuration>|null $options
* @param-out array<string, Configuration> $options
* @param array<string, string|array<int|string, string>> $dataToSet
* @return array<string,string> Error per item
*/
Expand All @@ -176,7 +177,7 @@ public function saveChanges(
}
unset($spec);

/** @var Configuration[] $options */
/** @var array<string, Configuration> $options */
$options = $options ?? $this->em->createQueryBuilder()
->from(Configuration::class, 'c', 'c.name')
->select('c')
Expand Down
2 changes: 1 addition & 1 deletion webapp/src/Service/EventLogService.php
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ public function log(

// Generate JSON content if not set, for deletes this is only the ID.
if ($action === self::ACTION_DELETE) {
$json = array_values(array_map(fn($id) => ['id' => (string)$id], $ids));
$json = array_map(fn($id) => ['id' => (string)$id], $ids);
} elseif ($json === null) {
$url = $type === 'contests' ? '' : ('/' . $type);

Expand Down
6 changes: 3 additions & 3 deletions webapp/src/Service/ExternalContestSourceService.php
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ public function getApiProviderName(): ?string
throw new LogicException('The contest source is not valid');
}

return $this->cachedApiInfoData?->provider?->name ?? $this->cachedApiInfoData?->name;
return $this->cachedApiInfoData?->provider->name ?? $this->cachedApiInfoData?->name;
}

public function getApiProviderVersion(): ?string
Expand All @@ -228,7 +228,7 @@ public function getApiProviderVersion(): ?string
throw new LogicException('The contest source is not valid');
}

return $this->cachedApiInfoData?->provider?->version ?? $this->cachedApiInfoData?->domjudge?->version;
return $this->cachedApiInfoData?->provider->version ?? $this->cachedApiInfoData?->domjudge?->version;
}

public function getApiProviderBuildDate(): ?string
Expand Down Expand Up @@ -1426,7 +1426,7 @@ protected function importSubmission(Event $event, EventData $data): void
}
} else {
// First, check if we actually have the source for this submission in the data.
if (empty($data->files[0]?->href)) {
if (empty($data->files[0]->href)) {
$this->addOrUpdateWarning($event, $data->id, ExternalSourceWarning::TYPE_SUBMISSION_ERROR, [
'message' => 'No source files in event',
]);
Expand Down
2 changes: 2 additions & 0 deletions webapp/src/Service/ICPCCmsService.php
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ public function importTeams(string $token, string $contest, ?string &$message =

/**
* Upload standings to the ICPC CMS
*
* @param-out string $message
*/
public function uploadStandings(string $token, string $contest, ?string &$message = null): bool
{
Expand Down
48 changes: 40 additions & 8 deletions webapp/src/Service/ImportExportService.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,35 @@ public function __construct(
/**
* Get the YAML data for a given contest.
*
* @return array<string, int|string|array<array{id: string, label: string, letter: string,
* name: string, color: string, rgb: string}>> $contest
* @return array{
* id: string,
* formal_name: string,
* name: string,
* start_time: string,
* end_time: string,
* duration: string,
* penalty_time: int,
* activate_time: string,
* warning_message?: string,
* medals: array{
* gold: int,
* silver: int,
* bronze: int
* },
* scoreboard_freeze_time?: string,
* scoreboard_freeze_duration?: string,
* scoreboard_thaw_time?: string,
* finalize_time?: string,
* deactivate_time?: string,
* problems?: list<array{
* id: string,
* label: string,
* letter: string,
* name: string,
* color: string|null,
* rgb: string|null,
* }>
* }
*/
public function getContestYamlData(Contest $contest, bool $includeProblems = true): array
{
Expand Down Expand Up @@ -390,7 +417,9 @@ public function importProblemsData(Contest $contest, array $problems, ?array &$i
$this->em->persist($contestProblem);
$this->em->flush();

$ids[] = $problem->getExternalid();
if ($problem->getExternalid()) {
$ids[] = $problem->getExternalid();
}
}

$this->em->flush();
Expand Down Expand Up @@ -862,7 +891,7 @@ public function importOrganizationsJson(array $data, ?string &$message = null, ?
/**
* Import organization data from the given array.
*
* @param array<array{externalid: string, shortname?: string, icpc_id?: string, name: string, country: string}> $organizationData
* @param array<array{externalid: string|null, shortname?: string, icpc_id?: string, name: string, country: string}> $organizationData
* @param TeamAffiliation[]|null $saved The saved groups
*
* @throws NonUniqueResultException
Expand Down Expand Up @@ -993,7 +1022,7 @@ protected function importTeamsTsv(array $content, ?string &$message = null): int
'name' => @$line[4],
'country' => @$line[6],
'externalid' => $affiliationExternalid,
]
],
];
}
return $this->importTeamData($teamData, $message);
Expand Down Expand Up @@ -1024,7 +1053,7 @@ public function importTeamsJson(array $data, ?string &$message = null, ?array &$
],
'team_affiliation' => [
'externalid' => $team['organization_id'] ?? null,
]
],
];
}

Expand Down Expand Up @@ -1158,6 +1187,7 @@ protected function importTeamData(array $teamData, ?string &$message, ?array &$s
$propertyAccessor = PropertyAccess::createPropertyAccessor();
foreach ($teamItem['team_affiliation'] as $field => $value) {
$propertyAccessor->setValue($teamAffiliation, $field, $value);
assert($teamAffiliation instanceof TeamAffiliation);
}
} else {
$teamAffiliation
Expand Down Expand Up @@ -1255,6 +1285,7 @@ protected function importTeamData(array $teamData, ?string &$message, ?array &$s
$propertyAccessor = PropertyAccess::createPropertyAccessor();
foreach ($teamItem['team'] as $field => $value) {
$propertyAccessor->setValue($team, $field, $value);
assert($team instanceof Team);
}

$errors = $this->validator->validate($team);
Expand Down Expand Up @@ -1333,7 +1364,7 @@ protected function importTeamData(array $teamData, ?string &$message, ?array &$s
* @param User[]|null $saved The saved users
* @param array<array{user: array{name: string|null, externalid: string, username: string,
* plain_password: string|null, teamid?: string|null,
* team?: array{name: string, category: string, externalid: string}|null,
* team?: Team|null,
* user_roles: Role[], ip_address: string|null},
* team?: array{name: string, externalid: string, category: TeamCategory,
* publicdescription?: string}}> $accountData
Expand All @@ -1351,7 +1382,7 @@ protected function importAccountData(
if (!empty($accountItem['team'])) {
$team = $this->em->getRepository(Team::class)->findOneBy([
'name' => $accountItem['team']['name'],
'category' => $accountItem['team']['category']
'category' => $accountItem['team']['category'],
]);
if ($team === null) {
$team = new Team();
Expand Down Expand Up @@ -1414,6 +1445,7 @@ protected function importAccountData(
$propertyAccessor = PropertyAccess::createPropertyAccessor();
foreach ($accountItem['user'] as $field => $value) {
$propertyAccessor->setValue($user, $field, $value);
assert($user instanceof User);
}

$errors = $this->validator->validate($user);
Expand Down
Loading
Loading