export.php 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. use Chamilo\CourseBundle\Entity\CSurveyQuestionOption;
  4. require_once __DIR__.'/../../main/inc/global.inc.php';
  5. api_protect_course_script(true);
  6. api_protect_teacher_script();
  7. $surveyId = isset($_GET['survey']) ? (int) $_GET['survey'] : 0;
  8. $surveyData = SurveyManager::get_survey($surveyId);
  9. $courseId = api_get_course_int_id();
  10. if (empty($surveyData)) {
  11. api_not_allowed(true);
  12. }
  13. $plugin = SurveyExportTxtPlugin::create();
  14. $allowExportIncomplete = 'true' === $plugin->get('export_incomplete');
  15. if ($plugin->get('enabled') !== 'true') {
  16. api_not_allowed(true);
  17. }
  18. $questionsData = SurveyManager::get_questions($surveyId, $courseId);
  19. // Sort questions by their "sort" field
  20. usort(
  21. $questionsData,
  22. function ($qL, $qR) {
  23. if ($qL['sort'] == $qR['sort']) {
  24. return 0;
  25. }
  26. return $qL['sort'] < $qR['sort'] ? -1 : 1;
  27. }
  28. );
  29. $content = [];
  30. $parts = [];
  31. $indexPart = 0;
  32. $numberOfQuestions = 0;
  33. // Separate questions in introduction and main blocks
  34. foreach ($questionsData as $questionData) {
  35. if (!in_array($questionData['type'], ['yesno', 'pagebreak', 'multiplechoice'])) {
  36. continue;
  37. }
  38. if ('pagebreak' === $questionData['type']) {
  39. $indexPart++;
  40. continue;
  41. }
  42. $numberOfQuestions++;
  43. if (0 === $indexPart) {
  44. $parts[0][] = $questionData;
  45. continue;
  46. }
  47. $parts[$indexPart][] = $questionData;
  48. }
  49. if (count($parts) < 2) {
  50. api_not_allowed(
  51. true,
  52. Display::return_message(get_lang('NoData'), 'warning')
  53. );
  54. }
  55. // Process introduction questions to show
  56. foreach ($parts[0] as $key => $introQuestion) {
  57. $content[] = chr($key + 97).'. '.strip_tags($introQuestion['question']);
  58. foreach ($introQuestion['answers'] as $answer) {
  59. $content[] = '>'.strip_tags($answer);
  60. }
  61. }
  62. $content[] = str_repeat('*', 40);
  63. // Get surveys by users
  64. $surveyAnswers = Database::getManager()
  65. ->createQuery(
  66. 'SELECT sa.user, MIN(sa.iid) AS id FROM ChamiloCourseBundle:CSurveyAnswer sa
  67. WHERE sa.cId = :course AND sa.surveyId = :survey
  68. GROUP BY sa.user ORDER BY id ASC'
  69. )
  70. ->setParameters(['course' => $courseId, 'survey' => $surveyId])
  71. ->getResult();
  72. // Process answers
  73. $i = 1;
  74. foreach ($surveyAnswers as $answer) {
  75. $userAnswersCount = 0;
  76. $surveyLine = '';
  77. // Show answers for introduction questions
  78. foreach ($parts[0] as $introQuestion) {
  79. $options = getQuestionOptions(
  80. $answer['user'],
  81. $courseId,
  82. $introQuestion['survey_id'],
  83. $introQuestion['question_id']
  84. );
  85. $userAnswersCount += count($options);
  86. /** @var CSurveyQuestionOption $option */
  87. foreach ($options as $option) {
  88. $surveyLine .= $option->getSort();
  89. }
  90. }
  91. $surveyLine .= '","';
  92. foreach ($parts as $z => $part) {
  93. if (0 === $z) {
  94. continue;
  95. }
  96. // Show answers for main questions
  97. foreach ($part as $mainQuestion) {
  98. $options = getQuestionOptions(
  99. $answer['user'],
  100. $courseId,
  101. $mainQuestion['survey_id'],
  102. $mainQuestion['question_id']
  103. );
  104. $userAnswersCount += count($options);
  105. /** @var CSurveyQuestionOption $option */
  106. foreach ($options as $option) {
  107. $surveyLine .= $option->getSort();
  108. }
  109. }
  110. }
  111. $surveyLine .= '"';
  112. if (!$allowExportIncomplete && $userAnswersCount < $numberOfQuestions) {
  113. continue;
  114. }
  115. $content[] = '"'.$i.'","'.$surveyLine;
  116. $i++;
  117. }
  118. // Add EOL to lines
  119. $fileContent = array_map(
  120. function ($line) {
  121. return html_entity_decode($line).PHP_EOL.PHP_EOL;
  122. },
  123. $content
  124. );
  125. // Generate file
  126. $fileName = api_get_path(SYS_ARCHIVE_PATH).md5($surveyId.time()).'.txt';
  127. file_put_contents($fileName, $fileContent);
  128. DocumentManager::file_send_for_download($fileName, true);
  129. /**
  130. * @param string $user
  131. * @param int $courseId
  132. * @param int $surveyId
  133. * @param int $questionId
  134. *
  135. * @return array
  136. */
  137. function getQuestionOptions($user, $courseId, $surveyId, $questionId)
  138. {
  139. $options = Database::getManager()
  140. ->createQuery(
  141. 'SELECT sqo FROM ChamiloCourseBundle:CSurveyQuestionOption sqo
  142. INNER JOIN ChamiloCourseBundle:CSurveyAnswer sa
  143. WITH
  144. sqo.cId = sa.cId
  145. AND sqo.questionId = sa.questionId
  146. AND sqo.surveyId = sa.surveyId
  147. AND sqo.iid = sa.optionId
  148. WHERE sa.user = :user AND sa.cId = :course AND sa.surveyId = :survey AND sa.questionId = :question'
  149. )
  150. ->setParameters(
  151. [
  152. 'user' => $user,
  153. 'course' => $courseId,
  154. 'survey' => $surveyId,
  155. 'question' => $questionId,
  156. ]
  157. )
  158. ->getResult();
  159. return $options;
  160. }