CQuizDistributionRepository.php 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. <?php
  2. namespace Entity\Repository;
  3. use Doctrine\ORM\EntityRepository;
  4. use Doctrine\Common\Collections\Criteria;
  5. use Doctrine\ORM\NoResultException;
  6. /**
  7. * CQuizDistributionRepository
  8. *
  9. */
  10. class CQuizDistributionRepository extends EntityRepository
  11. {
  12. /**
  13. * @param \Entity\CQuizDistribution $distribution
  14. * @param \Entity\Course $course
  15. */
  16. public function addDistribution(\Entity\CQuizDistribution $distribution, \Entity\Course $course)
  17. {
  18. $exerciseId = $distribution->getExerciseId();
  19. $exercise = new \Exercise($course->getId());
  20. $exercise->loadDistributions = true;
  21. $exercise->read($exerciseId);
  22. $questionList = $exercise->getQuestionList();
  23. $distribution->setDataTracking(implode(',', $questionList));
  24. $em = $this->getEntityManager();
  25. $em->persist($distribution);
  26. $em->flush();
  27. // 2. Registering quiz distribution + quiz distribution questions
  28. if ($distribution) {
  29. foreach ($questionList as $questionId) {
  30. $distributionQuestion = new \Entity\CQuizDistributionQuestions();
  31. $questionObj = \Question::read($questionId);
  32. $categories = $questionObj->get_categories_from_question();
  33. if (!empty($categories)) {
  34. $categoryId = current($categories);
  35. $distributionQuestion->setCategoryId($categoryId);
  36. }
  37. $distributionQuestion->setQuestionId($questionId);
  38. $distributionQuestion->setDistribution($distribution);
  39. $em->persist($distributionQuestion);
  40. }
  41. }
  42. // 3. Saving to the DB
  43. $em->flush();
  44. // 4. Getting questions per categories added in the current exercise // related via the matrix
  45. $categoriesInExercise = $exercise->get_categories_in_exercise();
  46. // 5. Getting questions from each category
  47. $questionsPerCategoryInExercise = array();
  48. if (!empty($categoriesInExercise)) {
  49. foreach ($categoriesInExercise as $categoryInfo) {
  50. $categoryId = $categoryInfo['category_id'];
  51. $questions = \Testcategory::getQuestionsByCategory($categoryId);
  52. $questionsPerCategoryInExercise[$categoryId] = $questions;
  53. }
  54. }
  55. // 6. Checking if the quiz distribution exists
  56. $criteria = array('quizDistributionId' => $distribution->getId());
  57. $currentDistributionQuestions = $em->getRepository('Entity\CQuizDistributionQuestions')->findBy($criteria);
  58. // 6. Checking if the quiz distribution exists
  59. $criteria = array('exerciseId' => $exerciseId);
  60. $distributionsInExercise = $em->getRepository('Entity\CQuizDistribution')->findBy($criteria);
  61. $distributionIdList = array();
  62. if ($distributionsInExercise) {
  63. foreach ($distributionsInExercise as $distributionItem) {
  64. // Avoid current dist
  65. if ($distributionItem->getId() == $distribution->getId()) {
  66. continue;
  67. }
  68. $distributionIdList[] = $distributionItem->getId();
  69. }
  70. }
  71. $questionsPerCategoryInDistribution = array();
  72. if (!empty($currentDistributionQuestions)) {
  73. /** @var \Entity\CQuizDistributionQuestions $question */
  74. foreach ($currentDistributionQuestions as $question) {
  75. $questionsPerCategoryInDistribution[$question->getCategoryId()][] = $question->getQuestionId();
  76. }
  77. /** @var \Entity\CQuizDistributionQuestions $question */
  78. foreach ($currentDistributionQuestions as $question) {
  79. $result = array();
  80. if (!empty($distributionIdList)) {
  81. // Checking if there are questions from this category that are not added yet
  82. $qb = $em->getRepository('Entity\CQuizDistributionQuestions')->createQueryBuilder('e');
  83. $qb->where('e.categoryId = :categoryId')
  84. ->andWhere('e.questionId = :questionId')
  85. ->andWhere($qb->expr()->in('e.quizDistributionId', $distributionIdList))
  86. ->setParameters(
  87. array(
  88. 'categoryId' => $question->getCategoryId(),
  89. 'questionId' => $question->getQuestionId()
  90. )
  91. )
  92. ;
  93. $result = $qb->getQuery()->getArrayResult();
  94. }
  95. // Doubles found
  96. if (count($result) > 0) {
  97. $questionListFromDistribution = $questionsPerCategoryInDistribution[$question->getCategoryId()];
  98. $questionListFromExercise = isset($questionsPerCategoryInExercise[$question->getCategoryId()]) ? $questionsPerCategoryInExercise[$question->getCategoryId()] : array();
  99. $diff = array_diff($questionListFromExercise, $questionListFromDistribution);
  100. // Found some questions. Great! now we can select one question.
  101. if (!empty($diff)) {
  102. shuffle($diff);
  103. $selectedQuestionId = current($diff);
  104. } else {
  105. // Nothing found take one random question from the question list in the exercise
  106. shuffle($questionListFromExercise);
  107. $selectedQuestionId = current($questionListFromExercise);
  108. }
  109. // $selectedQuestionId contains the new question id
  110. if (!empty($selectedQuestionId)) {
  111. $questionsPerCategoryInDistribution[$question->getCategoryId()][] = $selectedQuestionId;
  112. // Update the relationship
  113. $question->setQuestionId($selectedQuestionId);
  114. $em->persist($question);
  115. $em->flush();
  116. }
  117. }
  118. }
  119. $criteria = array('quizDistributionId' => $distribution->getId());
  120. $currentDistributionQuestions = $em
  121. ->getRepository('Entity\CQuizDistributionQuestions')
  122. ->findBy($criteria);
  123. $questionList = array();
  124. foreach ($currentDistributionQuestions as $question) {
  125. $questionList[] = $question->getQuestionId();
  126. }
  127. // Rebuild question list
  128. $distribution->setDataTracking(implode(',', $questionList));
  129. $em->persist($distribution);
  130. $em->flush();
  131. }
  132. }
  133. }