'time' => 'numeric',
]);
+ $round = Round::findOrFail($result->round_id);
+
if (isset($validatedData['disqualified'])) $result->disqualified = $validatedData['disqualified'];
if (isset($validatedData['forfeit'])) $result->forfeit = $validatedData['forfeit'];
if (isset($validatedData['time'])) $result->time = $validatedData['time'];
$result->save();
+ ResultChanged::dispatch($result);
+
Protocol::resultModified(
- $result->round->tournament,
+ $round->tournament,
$result,
$request->user(),
);
- ResultChanged::dispatch($result);
+ $round->load('results');
+ $round->updatePlacement();
+ if ($round->tournament->hasScoreboard()) {
+ $round->tournament->updatePlacement();
+ }
return $result->toJson();
}
public function unverify(Request $request, Result $result) {
$this->authorize('unverify', $result);
+ $round = Round::findOrFail($result->round_id);
+
$result->verified_at = null;
$result->verified_by()->associate(null);
$result->save();
+ ResultChanged::dispatch($result);
+
Protocol::resultUnverified(
- $result->round->tournament,
+ $round->tournament,
$result,
$request->user(),
);
- ResultChanged::dispatch($result);
-
return $result->toJson();
}
public function verify(Request $request, Result $result) {
$this->authorize('verify', $result);
+ $round = Round::findOrFail($result->round_id);
+
$result->verified_at = now();
$result->verified_by()->associate($request->user());
$result->save();
+ ResultChanged::dispatch($result);
+
Protocol::resultVerified(
- $result->round->tournament,
+ $round->tournament,
$result,
$request->user(),
);
- ResultChanged::dispatch($result);
-
return $result->toJson();
}
use HasFactory;
- public static function compareResult(Result $a, Result $b) {
- $a_time = !$a->forfeit ? $a->time : 0;
- $b_time = !$b->forfeit ? $b->time : 0;
+ public static function compareResult(Result $a, Result $b): int {
+ $a_time = $a->getEffectiveTime();
+ $b_time = $b->getEffectiveTime();
if ($a_time) {
if ($b_time) {
if ($a_time < $b_time) return -1;
if ($b_time) {
return 1;
}
+ if ($a->disqualified) {
+ if ($b->disqualified) {
+ return static::compareUsername($a, $b);
+ }
+ return 1;
+ }
+ if ($b->disqualified) {
+ return -1;
+ }
if ($a->forfeit) {
if ($b->forfeit) {
return static::compareUsername($a, $b);
}
- return -1;
+ return 1;
}
if ($b->forfeit) {
- return 1;
+ return -1;
}
return static::compareUsername($a, $b);
}
- public static function compareUsername(Result $a, Result $b) {
+ public static function compareUsername(Result $a, Result $b): int {
return strcasecmp($a->user->username, $b->user->username);
}
- public function formatTime() {
+ public function formatTime(): string {
$hours = floor($this->time / 60 / 60);
$minutes = floor(($this->time / 60) % 60);
$seconds = floor($this->time % 60);
return sprintf('%d:%02d:%02d', $hours, $minutes, $seconds);
}
- public function updateResult($time, $forfeit) {
+ public function getEffectiveTime(): float {
+ return ($this->disqualified || $this->forfeit) ? 0 : $this->time;
+ }
+
+ public function updateResult($time, $forfeit): void {
$this->time = $time;
$this->forfeit = $forfeit;
$this->save();
}
}
- public function updatePlacement($score, $placement) {
+ public function updatePlacement($score, $placement): void {
$this->score = $score;
$this->placement = $placement;
$this->save();
}
- public function hideResult(User $user = null) {
+ public function hideResult(User $user = null): void {
if (!$user || $this->user_id != $user->id) {
- $this->makeHidden(['forfeit', 'placement', 'score', 'time', 'vod']);
+ $this->makeHidden(['disqualified', 'forfeit', 'placement', 'score', 'time', 'vod']);
} else {
$this->makeHidden(['placement', 'score']);
}
public function isComplete() {
if (count($this->tournament->participants) == 0) return false;
- if ($this->tournament->type == 'open-async') return false;
+ if (!$this->tournament->hasFixedRunners()) return false;
if (count($this->results) == 0) return false;
foreach ($this->tournament->getRunners() as $participant) {
$result = $participant->findResult($this);
return true;
}
- public function updatePlacement() {
- if ($this->tournament->type == 'open-async') {
+ public function updatePlacement(): void {
+ if (!$this->tournament->hasFixedRunners()) {
$results = $this->results->sort([Result::class, 'compareResult']);
$reversed = $results->reverse();
$bonus = 1;
$lastResult = null;
foreach ($reversed as $result) {
- $betterThanLast = is_null($lastResult) || $result->time < $lastResult;
- if (!$result->forfeit && $betterThanLast) {
+ $betterThanLast = is_null($lastResult) || $result->getEffectiveTime() < $lastResult;
+ if (!$result->disqualified && !$result->forfeit && $betterThanLast) {
$running += $bonus;
- $lastResult = $result->time;
+ $lastResult = $result->getEffectiveTime();
$bonus = 1;
} else {
++$bonus;
}
- if (!$result->forfeit) {
- $result->updatePlacement($running, count($results) - $running + 1);
- } else {
+ if ($result->disqualified) {
+ $result->updatePlacement(0, count($results) + 1);
+ } elseif ($result->forfeit) {
$result->updatePlacement(0, count($results));
+ } else {
+ $result->updatePlacement($running, count($results) - $running + 1);
}
}
} else {
$mapped = array_map(function ($p) {
return ['participant' => $p, 'result' => $p->findResult($this)];
}, $runners);
- $filtered = array_filter($mapped, function($r) {
- return $r['result'] && ($r['result']->time || $r['result']->forfeit);
+ $filtered = array_filter($mapped, function ($r) {
+ return $r['result'] && ($r['result']->time || $r['result']->forfeit || $r['result']->disqualified);
});
$reversed = array_reverse($filtered);
$bonus = 1;
$lastResult = null;
foreach ($reversed as $r) {
- $betterThanLast = is_null($lastResult) || $r['result']->time < $lastResult;
- if (!$r['result']->forfeit && $betterThanLast) {
+ $betterThanLast = is_null($lastResult) || $r['result']->getEffectiveTime() < $lastResult;
+ if (!$r['result']->disqualified && !$r['result']->forfeit && $betterThanLast) {
$running += $bonus;
- $lastResult = $r['result']->time;
+ $lastResult = $r['result']->getEffectiveTime();
$bonus = 1;
} else {
++$bonus;
}
- if (!$r['result']->forfeit) {
- $r['result']->updatePlacement($running, count($filtered) - $running + 1);
- } else {
+ if ($r['result']->disqualified) {
+ $r['result']->updatePlacement(0, count($filtered) + 1);
+ } elseif ($r['result']->forfeit) {
$r['result']->updatePlacement(0, count($filtered));
+ } else {
+ $r['result']->updatePlacement($running, count($filtered) - $running + 1);
}
}
}
}
+ public function hasFixedRunners(): bool {
+ return in_array($this->type, ['signup-async']);
+ }
+
public function getRunners() {
$runners = [];
foreach ($this->participants as $participant) {
return $runners;
}
- public function hasScoreboard() {
+ public function hasScoreboard(): bool {
return $this->type == 'signup-async';
}