- Challenge modularization initiated
This commit is contained in:
		
							parent
							
								
									c1ba2ec74a
								
							
						
					
					
						commit
						7c533f91f0
					
				@ -38,7 +38,7 @@ class Game extends AutoStoring
 | 
			
		||||
 | 
			
		||||
    // -------
 | 
			
		||||
 | 
			
		||||
    static private function patchUpGameDate(array &$a) : void
 | 
			
		||||
    static private function patchUpGameData(array &$a) : void
 | 
			
		||||
    {
 | 
			
		||||
        $version = $a["version"] ?? 0;
 | 
			
		||||
        if ($version < 2) { // update to game version 2
 | 
			
		||||
@ -49,6 +49,13 @@ class Game extends AutoStoring
 | 
			
		||||
 | 
			
		||||
            $a["version"] = 2;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($version < 3) {
 | 
			
		||||
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
            //$a["version"] = 3;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Store modifications.
 | 
			
		||||
@ -106,7 +113,7 @@ class Game extends AutoStoring
 | 
			
		||||
    static function fromArray(GameMgr &$gameMgr, array $a): Game
 | 
			
		||||
    {
 | 
			
		||||
        $id = $a["_id"] ?? -1;
 | 
			
		||||
        self::patchUpGameDate($a);
 | 
			
		||||
        self::patchUpGameData($a);
 | 
			
		||||
        return new Game($gameMgr, $a["name"], $a["description"], $id, $a["owner"], $a["contributors"],
 | 
			
		||||
            $a["game_file_present"], $a["properties"], $a["public"], $a["public_id"], $a["version"]);
 | 
			
		||||
    }
 | 
			
		||||
@ -136,7 +143,7 @@ class Game extends AutoStoring
 | 
			
		||||
        return $a;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Export challenges to a CSV file.
 | 
			
		||||
    // Export challenges to a CSV file. TODO: ez csak a feleletválasztóshoz lesz jó
 | 
			
		||||
    function exportChallengesToCSV(&$f): void
 | 
			
		||||
    {
 | 
			
		||||
        // load challenges
 | 
			
		||||
@ -185,7 +192,7 @@ class Game extends AutoStoring
 | 
			
		||||
 | 
			
		||||
    const CSV_ENCODINGS = ["UTF-8", "Windows-1252"];
 | 
			
		||||
 | 
			
		||||
    // Import challenges from a CSV table.
 | 
			
		||||
    // Import challenges from a CSV table. TODO: ez csak a feleletválasztós betöltésére lesz jó
 | 
			
		||||
    function importChallengesFromCSV(string $csv_path): array
 | 
			
		||||
    {
 | 
			
		||||
        // convert text encoding into UTF-8
 | 
			
		||||
 | 
			
		||||
@ -79,7 +79,7 @@ class Answer
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class Challenge
 | 
			
		||||
class ChallengeReport
 | 
			
		||||
{
 | 
			
		||||
    private string $question;
 | 
			
		||||
    private array $answers;
 | 
			
		||||
@ -152,7 +152,7 @@ class ReportSection
 | 
			
		||||
    function __construct(string $title, array $challenges)
 | 
			
		||||
    {
 | 
			
		||||
        $this->title = $title;
 | 
			
		||||
        $this->challenges = array_map(fn($ch) => new Challenge($ch), $challenges);
 | 
			
		||||
        $this->challenges = array_map(fn($ch) => new ChallengeReport($ch), $challenges);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function getChallenges(): array
 | 
			
		||||
 | 
			
		||||
@ -13,15 +13,15 @@ const TEST_CONCLUDED = "concluded";
 | 
			
		||||
 | 
			
		||||
class TestSummary
 | 
			
		||||
{
 | 
			
		||||
    public int $challengeN; // Number of challenges
 | 
			
		||||
    public int $correctAnswerN; // Number of correct answers
 | 
			
		||||
    public int $maxMark; // Number of challenges
 | 
			
		||||
    public int $mark; // Number of correct answers
 | 
			
		||||
    private float $percentage; // Ratio of correct answers
 | 
			
		||||
 | 
			
		||||
    // Calculate percentage.
 | 
			
		||||
    private function calculatePercentage(): void
 | 
			
		||||
    {
 | 
			
		||||
        if ($this->challengeN > 0) {
 | 
			
		||||
            $this->percentage = $this->correctAnswerN / (double)$this->challengeN * 100.0;
 | 
			
		||||
        if ($this->maxMark > 0) {
 | 
			
		||||
            $this->percentage = $this->mark / (double)$this->maxMark * 100.0;
 | 
			
		||||
        } else { // avoid division by zero
 | 
			
		||||
            $this->percentage = 0.0;
 | 
			
		||||
        }
 | 
			
		||||
@ -29,45 +29,266 @@ class TestSummary
 | 
			
		||||
 | 
			
		||||
    function __construct(int $challengeN, int $correctAnswerN)
 | 
			
		||||
    {
 | 
			
		||||
        $this->challengeN = $challengeN;
 | 
			
		||||
        $this->correctAnswerN = $correctAnswerN;
 | 
			
		||||
        $this->maxMark = $challengeN;
 | 
			
		||||
        $this->mark = $correctAnswerN;
 | 
			
		||||
        $this->calculatePercentage();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Get challenge count.
 | 
			
		||||
    function getChallengeN(): int
 | 
			
		||||
    function getMaxMark(): int
 | 
			
		||||
    {
 | 
			
		||||
        return $this->challengeN;
 | 
			
		||||
        return $this->maxMark;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Get number of correct answers.
 | 
			
		||||
    function getCorrectAnswerN(): int
 | 
			
		||||
    function getMark(): int
 | 
			
		||||
    {
 | 
			
		||||
        return $this->correctAnswerN;
 | 
			
		||||
        return $this->mark;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function setCorrectAnswerN(int $correctAnswerN): void
 | 
			
		||||
    function setMark(int $mark): void
 | 
			
		||||
    {
 | 
			
		||||
        $this->correctAnswerN = $correctAnswerN;
 | 
			
		||||
        $this->mark = $mark;
 | 
			
		||||
        $this->calculatePercentage();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Get ratio of correct results.
 | 
			
		||||
    function getPercentage(): float
 | 
			
		||||
    {
 | 
			
		||||
        return ($this->correctAnswerN * 100.0) / $this->challengeN;
 | 
			
		||||
        return ($this->mark * 100.0) / $this->maxMark;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Build from array.
 | 
			
		||||
    static function fromArray(array $a): TestSummary
 | 
			
		||||
    {
 | 
			
		||||
        return new TestSummary($a["challenge_n"], $a["correct_answer_n"]);
 | 
			
		||||
        if (!isset($a["max_mark"]) || !isset($a["mark"])) { // backward compatibility
 | 
			
		||||
            return new TestSummary($a["challenge_n"], $a["correct_answer_n"]);
 | 
			
		||||
        } else {
 | 
			
		||||
            return new TestSummary($a["max_mark"], $a["mark"]);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Convert to array.
 | 
			
		||||
    function toArray(): array
 | 
			
		||||
    {
 | 
			
		||||
        return ["challenge_n" => $this->challengeN, "correct_answer_n" => $this->correctAnswerN, "percentage" => $this->percentage];
 | 
			
		||||
        return ["challenge_n" => $this->maxMark, "correct_answer_n" => $this->mark, "percentage" => $this->percentage];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class Challenge
 | 
			
		||||
{
 | 
			
		||||
    protected string $type; // challenge type
 | 
			
		||||
 | 
			
		||||
    protected float $max_mark; // maximum points that can be collected at this challenge
 | 
			
		||||
 | 
			
		||||
    protected bool $is_template; // this challenge is a template
 | 
			
		||||
 | 
			
		||||
    function __construct(string $type)
 | 
			
		||||
    {
 | 
			
		||||
        $this->type = $type;
 | 
			
		||||
        $this->is_template = false;
 | 
			
		||||
        $this->max_mark = 1.0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // save answer
 | 
			
		||||
    function saveAnswer(int|string $ans): bool
 | 
			
		||||
    {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // clear answer
 | 
			
		||||
    function clearAnswer(int|string $ans): bool
 | 
			
		||||
    {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // get challenge type
 | 
			
		||||
    function getType(): string
 | 
			
		||||
    {
 | 
			
		||||
        return $this->type;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function setMaxMark(float $max_mark): void
 | 
			
		||||
    {
 | 
			
		||||
        $this->max_mark = $max_mark;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function getMaxMark(): float {
 | 
			
		||||
        return $this->max_mark;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function getMark(): float
 | 
			
		||||
    {
 | 
			
		||||
        return 1.0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function toArray(): array
 | 
			
		||||
    {
 | 
			
		||||
        return ["type" => $this->type];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function setTemplate(bool $is_template): void
 | 
			
		||||
    {
 | 
			
		||||
        $this->is_template = $is_template;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function isTemplate(): bool
 | 
			
		||||
    {
 | 
			
		||||
        return $this->is_template;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function randomize(): void {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class PicturedChallenge extends Challenge
 | 
			
		||||
{
 | 
			
		||||
    protected string $image_url; // the URL of the corresponding image
 | 
			
		||||
 | 
			
		||||
    function __construct(string $type, array $a = null)
 | 
			
		||||
    {
 | 
			
		||||
        parent::__construct($type);
 | 
			
		||||
        $this->image_url = $a["image_url"] ?? "";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function setImageUrl(string $image_url): void
 | 
			
		||||
    {
 | 
			
		||||
        $this->image_url = $image_url;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function getImageUrl(): string
 | 
			
		||||
    {
 | 
			
		||||
        return $this->image_url;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function toArray(): array
 | 
			
		||||
    {
 | 
			
		||||
        $a = parent::toArray();
 | 
			
		||||
        $a["image_url"] = $this->image_url;
 | 
			
		||||
        return $a;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class SingleChoiceChallenge extends PicturedChallenge
 | 
			
		||||
{
 | 
			
		||||
    private string $question; // the task title
 | 
			
		||||
    private array $answers; // possible answers
 | 
			
		||||
    private int $correct_answer; // the single correct answer
 | 
			
		||||
 | 
			
		||||
    private int $player_answer; // answer given by the player
 | 
			
		||||
 | 
			
		||||
    // -----------------
 | 
			
		||||
 | 
			
		||||
    function __construct(array $a = null)
 | 
			
		||||
    {
 | 
			
		||||
        parent::__construct("singlechoice", $a);
 | 
			
		||||
 | 
			
		||||
        $this->question = $a["question"] ?? "";
 | 
			
		||||
        $this->answers = $a["answers"] ?? [];
 | 
			
		||||
        $this->correct_answer = (int)($a["correct_answer"] ?? -1);
 | 
			
		||||
        $this->player_answer = (int)($a["player_answer"] ?? -1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function setQuestion(string $question): void
 | 
			
		||||
    {
 | 
			
		||||
        $this->question = $question;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function getQuestion(): string
 | 
			
		||||
    {
 | 
			
		||||
        return $this->question;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function addAnswer(string $answer): void
 | 
			
		||||
    {
 | 
			
		||||
        $this->answers[] = $answer;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function getAnswers(): array
 | 
			
		||||
    {
 | 
			
		||||
        return $this->answers;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function setCorrectAnswer(string $correct_answer): void
 | 
			
		||||
    {
 | 
			
		||||
        $this->correct_answer = $correct_answer;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function getCorrectAnswer(): string
 | 
			
		||||
    {
 | 
			
		||||
        return $this->correct_answer;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function isAnswerIdInsideBounds($ansid): bool
 | 
			
		||||
    {
 | 
			
		||||
        return ($ansid >= 0) && ($ansid <= count($this->answers));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function saveAnswer(int|string $ans): bool
 | 
			
		||||
    {
 | 
			
		||||
        $ansidx = (int)($ans); // cast answer to integer as it is a number
 | 
			
		||||
        if ($this->isAnswerIdInsideBounds($ansidx)) {
 | 
			
		||||
            $this->player_answer = $ansidx;
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function clearAnswer(int|string $ans): bool
 | 
			
		||||
    {
 | 
			
		||||
        $ansidx = (int)($ans); // cast answer to integer as it is a number
 | 
			
		||||
        if ($this->isAnswerIdInsideBounds($ansidx)) {
 | 
			
		||||
            $this->player_answer = -1;
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getMark(): float
 | 
			
		||||
    {
 | 
			
		||||
        return ($this->player_answer == $this->correct_answer) ? 1.0 : 0.0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function toArray(): array
 | 
			
		||||
    {
 | 
			
		||||
        $a = parent::toArray();
 | 
			
		||||
        $a["question"] = $this->question;
 | 
			
		||||
        $a["answers"] = $this->answers;
 | 
			
		||||
        $a["correct_answer"] = $this->correct_answer;
 | 
			
		||||
        if (!$this->isTemplate()) {
 | 
			
		||||
            $a["player_answer"] = $this->player_answer;
 | 
			
		||||
        }
 | 
			
		||||
        return $a;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function randomize(): void{
 | 
			
		||||
        //shuffle($this->answers); // shuffle answers
 | 
			
		||||
        //$this->correct_answer = array_search($this->correct_answer, $this->answers); // remap correct answer
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class ChallengeFactory
 | 
			
		||||
{
 | 
			
		||||
    static function fromArray(array $a): Challenge|null
 | 
			
		||||
    {
 | 
			
		||||
        $type = $a["type"] ?? "singlechoice"; // if the type is missing, then it's a single choice challenge
 | 
			
		||||
        switch ($type) {
 | 
			
		||||
            case "singlechoice":
 | 
			
		||||
                return new SingleChoiceChallenge($a);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static function constructFromCollection(array $c): array {
 | 
			
		||||
        $chgs = [];
 | 
			
		||||
        foreach ($c as $ch) {
 | 
			
		||||
            $chgs[] = ChallengeFactory::fromArray($ch);
 | 
			
		||||
        }
 | 
			
		||||
        return $chgs;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -99,14 +320,23 @@ class Test extends AutoStoring
 | 
			
		||||
    private function preprocessChallenges(): void
 | 
			
		||||
    {
 | 
			
		||||
        foreach ($this->challenges as &$ch) {
 | 
			
		||||
            shuffle($ch["answers"]); // shuffle answers
 | 
			
		||||
            $ch["correct_answer"] = array_search($ch["correct_answer"], $ch["answers"]); // remap correct answer
 | 
			
		||||
            $ch["player_answer"] = -1; // create player answer field
 | 
			
		||||
            $ch->randomize();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // -------------
 | 
			
		||||
 | 
			
		||||
    function getMaxSumMark(): float
 | 
			
		||||
    {
 | 
			
		||||
        $msm = 0.0;
 | 
			
		||||
        foreach ($this->challenges as &$ch) {
 | 
			
		||||
            $msm += $ch->getMaxMark();
 | 
			
		||||
        }
 | 
			
		||||
        return $msm;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // -------------
 | 
			
		||||
 | 
			
		||||
    // Store modifications.
 | 
			
		||||
    public function storeMods(): void
 | 
			
		||||
    {
 | 
			
		||||
@ -136,11 +366,11 @@ class Test extends AutoStoring
 | 
			
		||||
            $this->endTime = $a["end_time"] ?? 0;
 | 
			
		||||
            $this->endLimitTime = $a["end_limit_time"] ?? 0;
 | 
			
		||||
            $this->repeatable = $a["repeatable"];
 | 
			
		||||
            $this->challenges = $a["challenges"];
 | 
			
		||||
            $this->challenges = ChallengeFactory::constructFromCollection($a["challenges"]);
 | 
			
		||||
            if (isset($a["summary"])) {
 | 
			
		||||
                $this->summary = TestSummary::fromArray($a["summary"]);
 | 
			
		||||
            } else { // backward compatibility
 | 
			
		||||
                $this->summary = new TestSummary(count($a["challenges"]), 0);
 | 
			
		||||
                $this->summary = new TestSummary($this->getMaxSumMark(), 0);
 | 
			
		||||
            }
 | 
			
		||||
        } else { // populating fields from Game and User objects
 | 
			
		||||
            $game = &$game_array;
 | 
			
		||||
@ -150,7 +380,7 @@ class Test extends AutoStoring
 | 
			
		||||
            // Fill-in basic properties
 | 
			
		||||
            $this->gameId = $game->getId();
 | 
			
		||||
            $this->gameName = $game->getName();
 | 
			
		||||
            $this->challenges = $game->getChallenges();
 | 
			
		||||
            $this->challenges = ChallengeFactory::constructFromCollection($game->getChallenges());
 | 
			
		||||
            $this->preprocessChallenges();
 | 
			
		||||
            $this->nickname = $user->getNickname();
 | 
			
		||||
 | 
			
		||||
@ -169,7 +399,7 @@ class Test extends AutoStoring
 | 
			
		||||
            $this->repeatable = $gp["repeatable"];
 | 
			
		||||
 | 
			
		||||
            // Create a blank summary
 | 
			
		||||
            $this->summary = new TestSummary(count($this->challenges), 0);
 | 
			
		||||
            $this->summary = new TestSummary($this->getMaxSumMark(), 0);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // auto-conclude time-constrained test if expired
 | 
			
		||||
@ -182,6 +412,11 @@ class Test extends AutoStoring
 | 
			
		||||
    // Convert test to array.
 | 
			
		||||
    function toArray(array $omit = []): array
 | 
			
		||||
    {
 | 
			
		||||
        $chgs = [];
 | 
			
		||||
        foreach ($this->challenges as $ch) {
 | 
			
		||||
            $chgs[] = $ch->toArray();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $a = [
 | 
			
		||||
            "_id" => $this->id,
 | 
			
		||||
            "gameid" => $this->gameId,
 | 
			
		||||
@ -193,7 +428,7 @@ class Test extends AutoStoring
 | 
			
		||||
            "end_time" => $this->endTime,
 | 
			
		||||
            "end_limit_time" => $this->endLimitTime,
 | 
			
		||||
            "repeatable" => $this->repeatable,
 | 
			
		||||
            "challenges" => $this->challenges,
 | 
			
		||||
            "challenges" => $chgs,
 | 
			
		||||
            "summary" => $this->summary->toArray()
 | 
			
		||||
        ];
 | 
			
		||||
 | 
			
		||||
@ -211,12 +446,16 @@ class Test extends AutoStoring
 | 
			
		||||
        return count($this->challenges);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function isChallengeIdInsideBounds(int $chidx): bool {
 | 
			
		||||
        return ($chidx >= 0) && ($chidx < $this->getChallengeCount());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Save answer. Asserting $safe prevents saving answers to a concluded test.
 | 
			
		||||
    function saveAnswer(int $chidx, int $ansidx, bool $safe = true): bool
 | 
			
		||||
    function saveAnswer(int $chidx, string $ans, bool $safe = true): bool
 | 
			
		||||
    {
 | 
			
		||||
        if (!$safe || $this->state === self::TEST_ONGOING) {
 | 
			
		||||
            if (($chidx < $this->getChallengeCount()) && ($ansidx < $this->challenges[$chidx]["answers"])) {
 | 
			
		||||
                $this->challenges[$chidx]["player_answer"] = $ansidx;
 | 
			
		||||
            if ($this->isChallengeIdInsideBounds($chidx)) {
 | 
			
		||||
                $this->challenges[$chidx]->saveAnswer($ans);
 | 
			
		||||
                $this->commitMods();
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
@ -228,8 +467,8 @@ class Test extends AutoStoring
 | 
			
		||||
    function clearAnswer(int $chidx, bool $safe = true): bool
 | 
			
		||||
    {
 | 
			
		||||
        if (!$safe || $this->state === self::TEST_ONGOING) {
 | 
			
		||||
            if ($chidx < $this->getChallengeCount()) {
 | 
			
		||||
                $this->challenges[$chidx]["player_answer"] = -1;
 | 
			
		||||
            if ($this->isChallengeIdInsideBounds($chidx)) {
 | 
			
		||||
                $this->challenges[$chidx]->clearAnswer();
 | 
			
		||||
                $this->commitMods();
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
@ -240,18 +479,16 @@ class Test extends AutoStoring
 | 
			
		||||
    // Conclude test.
 | 
			
		||||
    function concludeTest(): void
 | 
			
		||||
    {
 | 
			
		||||
        // check the answers
 | 
			
		||||
        $cans_n = 0; // number of correct answers
 | 
			
		||||
        // summarize points
 | 
			
		||||
        $mark_sum = 0.0;
 | 
			
		||||
        foreach ($this->challenges as &$ch) {
 | 
			
		||||
            if ($ch["player_answer"] === $ch["correct_answer"]) {
 | 
			
		||||
                $cans_n++;
 | 
			
		||||
            }
 | 
			
		||||
            $mark_sum += $ch->getMark();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // set state and fill summary
 | 
			
		||||
        $this->state = TEST_CONCLUDED;
 | 
			
		||||
        $this->endTime = time();
 | 
			
		||||
        $this->summary->setCorrectAnswerN($cans_n);
 | 
			
		||||
        $this->summary->setMark($mark_sum);
 | 
			
		||||
 | 
			
		||||
        // save test
 | 
			
		||||
        $this->commitMods();
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@ require_once "class/TestMgr.php";
 | 
			
		||||
 | 
			
		||||
const longopts = [
 | 
			
		||||
    "action:", // execute some CLI action
 | 
			
		||||
    "tick" // tick timed objects (e.g. timed tests)
 | 
			
		||||
    "tick", // tick timed objects (e.g. timed tests)
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
$options = getopt("", longopts);
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,7 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
ini_set("display_errors", true);
 | 
			
		||||
 | 
			
		||||
require_once "check_maintenance.php";
 | 
			
		||||
 | 
			
		||||
//ini_set('display_startup_errors', '1');
 | 
			
		||||
 | 
			
		||||
@ -46,7 +46,7 @@ function populate_infobox(test_data, view_only) {
 | 
			
		||||
                    time_left_s--;
 | 
			
		||||
                    print_timer();
 | 
			
		||||
                    if (time_left_s <= 0) {
 | 
			
		||||
                        populate_all(test_data["_id"], test_data["gameid"]);
 | 
			
		||||
                        populate_all(test_data["_id"], test_data["gameid"], false);
 | 
			
		||||
                        clearInterval(INTERVAL_HANDLE);
 | 
			
		||||
                        INTERVAL_HANDLE = null;
 | 
			
		||||
                    }
 | 
			
		||||
@ -183,6 +183,6 @@ function submit_test() {
 | 
			
		||||
        testid: TEST_DATA["_id"]
 | 
			
		||||
    }
 | 
			
		||||
    request(req).then(resp => {
 | 
			
		||||
        populate_all(TEST_DATA["_id"], TEST_DATA["gameid"]);
 | 
			
		||||
        populate_all(TEST_DATA["_id"], TEST_DATA["gameid"], false);
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
@ -5,7 +5,9 @@
 | 
			
		||||
    <title>SpreadQuiz :: Karbantartás</title>
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
<img src="media/maintenance.png" width="180">
 | 
			
		||||
<h3> Az oldal karbantartás alatt áll!</h3>
 | 
			
		||||
<section style="margin: 0 auto; padding-top: 10ex; text-align: center">
 | 
			
		||||
    <img src="media/maintenance.png" style="width: 16vw">
 | 
			
		||||
    <h3 style="font-family: 'Monaco', monospace"> Az oldal karbantartás alatt áll!</h3>
 | 
			
		||||
</section>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user