mirror of
https://github.com/MarijnDoeve/TijdVoorDeTest.git
synced 2026-03-06 04:44:19 +01:00
Refactor repositories to use DQL queries, simplify logic, and enhance query efficiency
This commit is contained in:
5
.idea/php.xml
generated
5
.idea/php.xml
generated
@@ -26,6 +26,11 @@
|
|||||||
<phpcs_fixer_by_interpreter asDefaultInterpreter="true" deletedFromTheList="true" interpreter_id="96512cb2-7b9e-4e1d-bfa2-bf7f3be424c8" standards="DoctrineAnnotation;PER;PER-CS;PER-CS1.0;PER-CS2.0;PHP54Migration;PHP56Migration;PHP70Migration;PHP71Migration;PHP73Migration;PHP74Migration;PHP80Migration;PHP81Migration;PHP82Migration;PHP83Migration;PHP84Migration;PHPUnit100Migration;PHPUnit30Migration;PHPUnit32Migration;PHPUnit35Migration;PHPUnit43Migration;PHPUnit48Migration;PHPUnit50Migration;PHPUnit52Migration;PHPUnit54Migration;PHPUnit55Migration;PHPUnit56Migration;PHPUnit57Migration;PHPUnit60Migration;PHPUnit75Migration;PHPUnit84Migration;PHPUnit91Migration;PSR1;PSR12;PSR2;PhpCsFixer;Symfony" tool_path="vendor/bin/php-cs-fixer" timeout="30000" />
|
<phpcs_fixer_by_interpreter asDefaultInterpreter="true" deletedFromTheList="true" interpreter_id="96512cb2-7b9e-4e1d-bfa2-bf7f3be424c8" standards="DoctrineAnnotation;PER;PER-CS;PER-CS1.0;PER-CS2.0;PHP54Migration;PHP56Migration;PHP70Migration;PHP71Migration;PHP73Migration;PHP74Migration;PHP80Migration;PHP81Migration;PHP82Migration;PHP83Migration;PHP84Migration;PHPUnit100Migration;PHPUnit30Migration;PHPUnit32Migration;PHPUnit35Migration;PHPUnit43Migration;PHPUnit48Migration;PHPUnit50Migration;PHPUnit52Migration;PHPUnit54Migration;PHPUnit55Migration;PHPUnit56Migration;PHPUnit57Migration;PHPUnit60Migration;PHPUnit75Migration;PHPUnit84Migration;PHPUnit91Migration;PSR1;PSR12;PSR2;PhpCsFixer;Symfony" tool_path="vendor/bin/php-cs-fixer" timeout="30000" />
|
||||||
</phpcsfixer_settings>
|
</phpcsfixer_settings>
|
||||||
</component>
|
</component>
|
||||||
|
<component name="PhpCodeSniffer">
|
||||||
|
<phpcs_settings>
|
||||||
|
<phpcs_by_interpreter asDefaultInterpreter="true" interpreter_id="96512cb2-7b9e-4e1d-bfa2-bf7f3be424c8" timeout="30000" />
|
||||||
|
</phpcs_settings>
|
||||||
|
</component>
|
||||||
<component name="PhpExternalFormatter">
|
<component name="PhpExternalFormatter">
|
||||||
<option name="externalFormatter" value="PHP_CS_FIXER" />
|
<option name="externalFormatter" value="PHP_CS_FIXER" />
|
||||||
</component>
|
</component>
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ security:
|
|||||||
# Note: Only the *first* access control that matches will be used
|
# Note: Only the *first* access control that matches will be used
|
||||||
access_control:
|
access_control:
|
||||||
- { path: ^/admin, roles: ROLE_ADMIN }
|
- { path: ^/admin, roles: ROLE_ADMIN }
|
||||||
# - { path: ^/profile, roles: ROLE_USER }
|
- { path: ^/backoffice, roles: ROLE_USER }
|
||||||
|
|
||||||
when@test:
|
when@test:
|
||||||
security:
|
security:
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ class QuizController extends AbstractController
|
|||||||
#[Route(
|
#[Route(
|
||||||
'/backoffice/season/{seasonCode:season}/quiz/{quiz}/enable',
|
'/backoffice/season/{seasonCode:season}/quiz/{quiz}/enable',
|
||||||
name: 'app_backoffice_enable',
|
name: 'app_backoffice_enable',
|
||||||
requirements: ['seasonCode' => self::SEASON_CODE_REGEX, 'quiz' => Requirement::UUID],
|
requirements: ['seasonCode' => self::SEASON_CODE_REGEX, 'quiz' => Requirement::UUID.'|null'],
|
||||||
)]
|
)]
|
||||||
#[IsGranted(SeasonVoter::EDIT, subject: 'season')]
|
#[IsGranted(SeasonVoter::EDIT, subject: 'season')]
|
||||||
public function enableQuiz(Season $season, ?Quiz $quiz, EntityManagerInterface $em): RedirectResponse
|
public function enableQuiz(Season $season, ?Quiz $quiz, EntityManagerInterface $em): RedirectResponse
|
||||||
|
|||||||
@@ -34,12 +34,14 @@ class CandidateRepository extends ServiceEntityRepository
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->createQueryBuilder('c')
|
return $this->getEntityManager()->createQuery(<<<DQL
|
||||||
->where('c.season = :season')
|
select c from App\Entity\Candidate c
|
||||||
->andWhere('lower(c.name) = lower(:name)')
|
where c.season = :season
|
||||||
->setParameter('season', $season)
|
and lower(c.name) = lower(:name)
|
||||||
|
DQL
|
||||||
|
)->setParameter('season', $season)
|
||||||
->setParameter('name', $name)
|
->setParameter('name', $name)
|
||||||
->getQuery()->getOneOrNullResult();
|
->getOneOrNullResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function save(Candidate $candidate, bool $flush = true): void
|
public function save(Candidate $candidate, bool $flush = true): void
|
||||||
@@ -54,44 +56,22 @@ class CandidateRepository extends ServiceEntityRepository
|
|||||||
/** @return ResultList */
|
/** @return ResultList */
|
||||||
public function getScores(Quiz $quiz): array
|
public function getScores(Quiz $quiz): array
|
||||||
{
|
{
|
||||||
$qb = $this->createQueryBuilder('c', 'c.id')
|
return $this->getEntityManager()->createQuery(<<<DQL
|
||||||
->select('c.id', 'c.name', 'sum(case when a.isRightAnswer = true then 1 else 0 end) as correct', 'qc.corrections', 'max(ga.created) - qc.created as time')
|
select
|
||||||
->join('c.givenAnswers', 'ga')
|
c.id,
|
||||||
->join('ga.answer', 'a')
|
c.name,
|
||||||
->join('c.quizData', 'qc')
|
sum(case when a.isRightAnswer = true then 1 else 0 end) as correct,
|
||||||
->where('qc.quiz = :quiz')
|
qc.corrections,
|
||||||
->groupBy('ga.quiz', 'c.id', 'qc.id')
|
max(ga.created) - qc.created as time,
|
||||||
->setParameter('quiz', $quiz);
|
(sum(case when a.isRightAnswer = true then 1 else 0 end) + qc.corrections) as score
|
||||||
|
from App\Entity\Candidate c
|
||||||
return $this->sortResults(
|
join c.givenAnswers ga
|
||||||
$this->calculateScore(
|
join ga.answer a
|
||||||
$qb->getQuery()->getResult(),
|
join c.quizData qc
|
||||||
),
|
where qc.quiz = :quiz
|
||||||
);
|
group by ga.quiz, c.id, qc.id
|
||||||
}
|
order by score desc, time desc
|
||||||
|
DQL
|
||||||
/**
|
)->setParameter('quiz', $quiz)->getResult();
|
||||||
* @param array<string, array{id: Uuid, name: string, correct: int, time: \DateInterval, corrections: float}> $in
|
|
||||||
*
|
|
||||||
* @return array<string, Result>
|
|
||||||
*/
|
|
||||||
private function calculateScore(array $in): array
|
|
||||||
{
|
|
||||||
return array_map(static fn ($candidate): array => [
|
|
||||||
...$candidate,
|
|
||||||
'score' => $candidate['correct'] + $candidate['corrections'],
|
|
||||||
], $in);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param array<string, Result> $results
|
|
||||||
*
|
|
||||||
* @return ResultList
|
|
||||||
* */
|
|
||||||
private function sortResults(array $results): array
|
|
||||||
{
|
|
||||||
usort($results, static fn ($a, $b): int => $b['score'] <=> $a['score']);
|
|
||||||
|
|
||||||
return $results;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ declare(strict_types=1);
|
|||||||
namespace App\Repository;
|
namespace App\Repository;
|
||||||
|
|
||||||
use App\Entity\Candidate;
|
use App\Entity\Candidate;
|
||||||
use App\Entity\GivenAnswer;
|
|
||||||
use App\Entity\Question;
|
use App\Entity\Question;
|
||||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||||
use Doctrine\Persistence\ManagerRegistry;
|
use Doctrine\Persistence\ManagerRegistry;
|
||||||
@@ -22,22 +21,21 @@ class QuestionRepository extends ServiceEntityRepository
|
|||||||
|
|
||||||
public function findNextQuestionForCandidate(Candidate $candidate): ?Question
|
public function findNextQuestionForCandidate(Candidate $candidate): ?Question
|
||||||
{
|
{
|
||||||
$qb = $this->createQueryBuilder('q');
|
return $this->getEntityManager()->createQuery(<<<DQL
|
||||||
|
select q from App\Entity\Question q
|
||||||
return $qb->join('q.quiz', 'qz')
|
join q.quiz qz
|
||||||
->andWhere($qb->expr()->notIn('q.id', $this->getEntityManager()->createQueryBuilder()
|
where q.id not in (
|
||||||
->select('q1')
|
select q1.id from App\Entity\GivenAnswer ga
|
||||||
->from(GivenAnswer::class, 'ga')
|
join ga.answer a
|
||||||
->join('ga.answer', 'a')
|
join a.question q1
|
||||||
->join('a.question', 'q1')
|
where ga.candidate = :candidate
|
||||||
->andWhere($qb->expr()->isNotNull('ga.answer'))
|
and q1.quiz = :quiz
|
||||||
->andWhere('ga.candidate = :candidate')
|
)
|
||||||
->andWhere('q1.quiz = :quiz')
|
and qz = :quiz
|
||||||
->getDQL()))
|
DQL)
|
||||||
->andWhere('qz = :quiz')
|
|
||||||
->setMaxResults(1)
|
->setMaxResults(1)
|
||||||
->setParameter('candidate', $candidate)
|
->setParameter('candidate', $candidate)
|
||||||
->setParameter('quiz', $candidate->getSeason()->getActiveQuiz())
|
->setParameter('quiz', $candidate->getSeason()->getActiveQuiz())
|
||||||
->getQuery()->getOneOrNullResult();
|
->getOneOrNullResult();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,11 +22,9 @@ class SeasonRepository extends ServiceEntityRepository
|
|||||||
/** @return list<Season> Returns an array of Season objects */
|
/** @return list<Season> Returns an array of Season objects */
|
||||||
public function getSeasonsForUser(User $user): array
|
public function getSeasonsForUser(User $user): array
|
||||||
{
|
{
|
||||||
$qb = $this->createQueryBuilder('s')
|
return $this->getEntityManager()->createQuery(<<<DQL
|
||||||
->where(':user MEMBER OF s.owners')
|
select s from App\Entity\Season s where :user member of s.owners order by s.name
|
||||||
->orderBy('s.name')
|
DQL
|
||||||
->setParameter('user', $user);
|
)->setParameter('user', $user)->getResult();
|
||||||
|
|
||||||
return $qb->getQuery()->getResult();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user