<?php
namespace App\Entity\Core\Training;
use App\Entity\Core\Answer;
use App\Entity\Core\Session\Session;
use App\Entity\Core\Topic\TopicCounterInterface;
use App\Entity\Core\Topic\TopicCounterTrait;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Exception;
use JsonSerializable;
#[ORM\Table('training_unit')]
#[ORM\Entity(repositoryClass: TrainingUnitRepository::class)]
class TrainingUnit implements TopicCounterInterface, JsonSerializable
{
use TopicCounterTrait;
/**
* @var int
*/
#[ORM\Column(name: 'id', type: 'integer')]
#[ORM\Id]
#[ORM\GeneratedValue(strategy: 'AUTO')]
private $id;
/**
* @var Session
*/
#[ORM\JoinColumn(name: 'session', referencedColumnName: 'id', onDelete: 'CASCADE')]
#[ORM\ManyToOne(targetEntity: Session::class, inversedBy: 'TrainingUnits')]
private $session;
/**
* @var Collection
*/
#[ORM\OneToMany(targetEntity: TrainingStudent::class, mappedBy: 'trainingUnit', cascade: ['persist', 'remove'])]
private $TrainingStudents;
/**
* @var TrainingResponse[]
*/
#[ORM\OneToMany(targetEntity: TrainingResponse::class, mappedBy: 'trainingUnit', cascade: ['persist', 'remove'])]
private $TrainingResponses;
#[ORM\Column(type: 'array', nullable: true)]
private $currentAnswers = [];
public function __construct()
{
$this->TrainingStudents = new ArrayCollection();
$this->TrainingResponses = new ArrayCollection();
}
/**
* Get id.
*
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* Set Session.
*
* @param Session $session
*
* @return TrainingUnit
*/
public function setSession($session)
{
$this->session = $session;
return $this;
}
/**
* Get Session.
*/
public function getSession(): ?Session
{
return $this->session;
}
public function getTrainingStudents(): Collection
{
return $this->TrainingStudents;
}
/**
* @return TrainingUnit
*/
public function addTrainingStudent(TrainingStudent $TrainingStudent)
{
$TrainingStudent->setTrainingUnit($this);
$this->TrainingStudents->add($TrainingStudent);
return $this;
}
/**
* @return bool
*/
public function removeTrainingStudent(TrainingStudent $TrainingStudent)
{
$TrainingStudent->setTrainingUnit(null);
return $this->TrainingStudents->removeElement($TrainingStudent);
}
/**
* @return TrainingResponse[]
*/
public function getTrainingResponses()
{
return $this->TrainingResponses;
}
/**
* @return array
*/
public function getValidTrainingResponses()
{
$trainingResponses = [];
foreach ($this->TrainingResponses as $response) {
if ($response->isValid()) {
$trainingResponses[] = $response;
}
}
return $trainingResponses;
}
/**
* @return TrainingUnit
*/
public function addTrainingResponse(TrainingResponse $TrainingResponse)
{
$TrainingResponse->setTrainingUnit($this);
$this->TrainingResponses->add($TrainingResponse);
return $this;
}
/**
* @return bool
*/
public function removeTrainingResponse(TrainingResponse $TrainingResponse)
{
$TrainingResponse->setTrainingUnit(null);
return $this->TrainingResponses->removeElement($TrainingResponse);
}
/**
* @return int
*/
public function getCorrectAnswerCount()
{
$correctCount = 0;
foreach ($this->TrainingResponses as $answer) {
if ($answer->getAnswerChosen() !== null && $answer->getAnswerChosen()->getIsCorrect()) {
$correctCount++;
}
}
return $correctCount;
}
/**
* @return int
*/
public function getMeanDifficultyFromCorrect()
{
$correctCount = 0;
$totalDifficulty = 0;
foreach ($this->TrainingResponses as $answer) {
if ($answer->getAnswerChosen() !== null && $answer->getAnswerChosen()->getIsCorrect()) {
$correctCount++;
try{
$totalDifficulty += $answer->getMathproblem()->getTemplate()->getDifficulty();
} catch (Exception $e){
// although it shouldn't fail due to non nullable constraints,
// the effect of an answer not having difficulty shouldn't
// impact on the result. (silently fail)
}
}
}
if($correctCount === 0){
return -2;
}
return $totalDifficulty/$correctCount;
}
/**
* @return int
*/
public function getIncorrectAnswerCount()
{
return count($this->TrainingResponses) - $this->getCorrectAnswerCount();
}
/**
* @return TrainingStudent
*/
public function getTeamLeader()
{
foreach ($this->TrainingStudents as $student) {
if ($student->getIsTeamLeader()) {
return $student;
}
}
return null;
}
public function getCurrentAnswers()
{
return $this->currentAnswers;
}
public function setStudentsCurrentAnswer(TrainingStudent $trainingStudent, Answer $answer)
{
$this->currentAnswers[$trainingStudent->getStudent()->getId()] = $answer->getId();
}
public function checkCurrentAnswers()
{
return count(array_unique(array_values($this->currentAnswers))) === 1 &&
count($this->currentAnswers) == count($this->TrainingStudents);
}
public function jsonSerialize(): mixed
{
return [
"id" => $this->getId(),
"correctAnswerCount" => $this->getCorrectAnswerCount(),
"currentAnswers" => $this->getCurrentAnswers(),
"incorrectAnswerCount" => $this->getIncorrectAnswerCount(),
"meanDifficultyFromCorrect" => $this->getMeanDifficultyFromCorrect(),
"teamLeader" => $this->getTeamLeader(),
"trainingStudents" => $this->getTrainingStudents()->toArray(),
"validTrainingResponses" => $this->getValidTrainingResponses(),
"currentTopicNr" => $this->getCurrentTopicNr(),
];
}
}