args); $v->rule('required', [ 'title', ])->rule('lengthMin', 'title', 1) ->rule('int', 'multipleOptions') ->rule('date', 'endDate') ->rule('stringArray', 'options') ->rule('boolean', 'keepOldVote'); if (!$v->validate()) { return $v->errorStr(); } return null; } function closeOldVote(int $voteID, KVStorage $voteStor, GameClock $clock) { $db = DB::db(); $voteStor = KVStorage::getStorage($db, 'vote'); $rawLastVoteInfo = $voteStor->getValue("vote_{$voteID}"); if (!$rawLastVoteInfo) { return; } $rawLastVoteInfo = VoteInfo::normalizeGameStorage($rawLastVoteInfo, $clock); if ($rawLastVoteInfo['endTick'] !== null) { return; } $rawLastVoteInfo['endTick'] = $clock->nowTick(); $rawLastVoteInfo['endDate'] = $clock->formatTick($rawLastVoteInfo['endTick']); $voteStor->setValue("vote_{$voteID}", $rawLastVoteInfo); } function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag): null | string | array | APIRecoveryType { $isVoteAdmin = in_array('vote', $session->acl[DB::prefix()] ?? []); $isVoteAdmin = $isVoteAdmin || $session->userGrade >= 5; if (!$isVoteAdmin) { return "권한이 부족합니다."; } /** @var string */ $title = $this->args['title']; /** @var int */ $multipleOptions = $this->args['multipleOptions'] ?? 1; if ($multipleOptions < 0) { $multipleOptions = 0; } $db = DB::db(); $gameStor = KVStorage::getStorage($db, 'game_env'); $clock = GameClock::fromStorage($gameStor); $nowTick = $clock->nowTick(); $now = $clock->formatTick($nowTick); /** @var ?string */ $endDate = $this->args['endDate'] ?? null; /** @var string[] */ $options = $this->args['options'] ?? []; if(!$options){ return '항목이 없습니다.'; } if($endDate !== null){ try{ $oEndDate = new \DateTimeImmutable($endDate); $endTick = $clock->dateTimeToTick($oEndDate); if($endTick < $nowTick){ return '종료일이 이미 지났습니다.'; } } catch(\Throwable $e){ return '종료일이 잘못되었습니다.'.$e->getMessage(); } } $userName = $session->userName; $lastVote = $gameStor->getValue('lastVote') ?? 0; $voteID = $lastVote + 1; $voteStor = KVStorage::getStorage($db, 'vote'); if (!($this->args['keepOldVote'] ?? false)) { $this->closeOldVote($lastVote, $voteStor, $clock); } $multipleOptions = Util::valueFit($multipleOptions, 0, count($options)); $voteInfo = new VoteInfo( id: $voteID, title: $title, opener: $userName ?? '[SYSTEM]', multipleOptions: $multipleOptions, startDate: $now, endDate: $endDate, options: $options, ); $voteStor->setValue("vote_{$voteID}", $voteInfo->toArray() + [ 'startTick' => $nowTick, 'endTick' => $endDate === null ? null : $clock->dateTimeToTick(new \DateTimeImmutable($endDate)), ]); $gameStor->setValue('lastVote', $voteID); $db->update('general', [ 'newvote' => 1 ], true); return [ 'result' => true ]; } }