PageRenderTime 50ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/php/lib/export_manager/component/survey_ods_exporter.class.php

https://bitbucket.org/chamilo/chamilo-app-survey/
PHP | 528 lines | 359 code | 119 blank | 50 comment | 21 complexity | e59a83965796c1aed02a6e1e7e4901b8 MD5 | raw file
  1. <?php
  2. namespace application\survey;
  3. use group\GroupDataManager;
  4. use repository\content_object\survey_multiple_choice_question\SurveyMultipleChoiceQuestion;
  5. use repository\content_object\survey_matrix_question\SurveyMatrixQuestion;
  6. use tracking\Tracker;
  7. use common\libraries\AndCondition;
  8. use common\libraries\EqualityCondition;
  9. use common\libraries\InCondition;
  10. use common\libraries\Translation;
  11. use common\libraries\Utilities;
  12. use common\libraries\Request;
  13. use common\libraries\path;
  14. use reporting\ReportingData;
  15. use Ods\Ods;
  16. require_once Path :: get_plugin_path() . '/odsPHP/ods.php';
  17. class SurveyExportManagerSurveyOdsExporterComponent extends SurveyExportManager
  18. {
  19. const COUNT = 'count';
  20. const TOTAL = 'total';
  21. const NOT_STARTED_PARTICIPANTS = 'not_started_participants';
  22. const STARTED_PARTICIPANTS = 'started_participants';
  23. const ALL_PARTICIPANTS = 'all_participants';
  24. const NOT_STARTED_PARTICIPANT_COUNT = 'not_started_participant_count';
  25. const STARTED_PARTICIPANT_COUNT = 'started_participant_count';
  26. const ALL_PARTICIPANT_COUNT = 'all_participant_count';
  27. const CONTEXTS = 'groups';
  28. const CONTEXT_NAME = 'group_name';
  29. const CONTEXT_DESCRIPTION = 'group_description';
  30. const INDIVIDUAL_USERS = 'individual_users';
  31. const USERS = 'users';
  32. const PARTICIPATION_GRADE = 'participation_grade';
  33. const SURVEYS = 'surveys';
  34. const SURVEY_NAME = 'survey_name';
  35. const SURVEY_DESCRIPTION = 'survey_description';
  36. const SURVEY_COUNT = 'survey_count';
  37. const REPORTING_DATA = 'reporting_data';
  38. const DATA_NAME = 'data_name';
  39. const DATA_DESCRIPTION = 'data_description';
  40. const DATA_GROUP = 'data_group';
  41. private $participants;
  42. private $surveys;
  43. /**
  44. * Runs this component and displays its output.
  45. */
  46. function run()
  47. {
  48. $ids = Request :: get(SurveyExportManager :: PARAM_PUBLICATION_ID);
  49. if (! is_array($ids))
  50. {
  51. $ids = array($ids);
  52. }
  53. $this->create_participants($ids);
  54. $this->render_data();
  55. }
  56. public function render_data()
  57. {
  58. $ods = new Ods();
  59. $questions = $this->get_questions();
  60. header('Content-Type: application/vnd.oasis.opendocument.spreadsheet');
  61. header('Content-Disposition: attachment;filename="' . 'survey_export' . '.ods"');
  62. header('Cache-Control: max-age=0');
  63. $objWriter = $ods->array2Ods();
  64. return $objWriter->save('php://output');
  65. }
  66. private function get_questions()
  67. {
  68. $page_questions = array();
  69. $surveys = $this->surveys;
  70. foreach ($surveys as $survey)
  71. {
  72. $pages = $survey->get_pages();
  73. foreach ($pages as $page)
  74. {
  75. if ($page->count_questions() != 0)
  76. {
  77. $questions = $page->get_questions();
  78. foreach ($questions as $question)
  79. {
  80. $page_questions[$question->get_id()] = $question;
  81. }
  82. }
  83. }
  84. }
  85. return $page_questions;
  86. }
  87. private function create_page_reporting_data($question)
  88. {
  89. $page_reporting_data = array();
  90. $all_participants_ids = $this->participants[self :: ALL_PARTICIPANTS];
  91. $reporting_data = $this->create_reporting_data($question, $all_participants_ids);
  92. $reporting_data_question = array();
  93. $reporting_data_question[self :: DATA_GROUP] = Translation :: get(AllGroups);
  94. $reporting_data_question[self :: DATA_NAME] = $question->get_title();
  95. $reporting_data_question[self :: DATA_DESCRIPTION] = $question->get_description();
  96. $reporting_data_question[self :: STARTED_PARTICIPANT_COUNT] = $this->participants[self :: STARTED_PARTICIPANT_COUNT];
  97. $reporting_data_question[self :: REPORTING_DATA] = $reporting_data;
  98. $page_reporting_data[] = $reporting_data_question;
  99. $groups = $this->participants[self :: GROUPS];
  100. foreach ($groups as $group)
  101. {
  102. $reporting_data_question = array();
  103. $reporting_data_question[self :: DATA_GROUP] = $group[self :: GROUP_DESCRIPTION];
  104. $reporting_data_question[self :: DATA_NAME] = $question->get_title();
  105. $reporting_data_question[self :: DATA_DESCRIPTION] = $question->get_description();
  106. $reporting_data_question[self :: STARTED_PARTICIPANT_COUNT] = $group[self :: STARTED_PARTICIPANT_COUNT];
  107. $all_participants_ids = $group[self :: ALL_PARTICIPANTS];
  108. $reporting_data = $this->create_reporting_data($question, $all_participants_ids);
  109. $reporting_data_question[self :: REPORTING_DATA] = $reporting_data;
  110. $page_reporting_data[] = $reporting_data_question;
  111. }
  112. return $page_reporting_data;
  113. }
  114. private function create_reporting_data($question, $participant_ids)
  115. {
  116. //retrieve the answer trackers
  117. $conditions = array();
  118. $conditions[] = new InCondition(SurveyQuestionAnswerTracker :: PROPERTY_SURVEY_PARTICIPANT_ID, $participant_ids);
  119. $conditions[] = new EqualityCondition(SurveyQuestionAnswerTracker :: PROPERTY_COMPLEX_QUESTION_ID, $question->get_id());
  120. $condition = new AndCondition($conditions);
  121. $trackers = Tracker :: get_data('survey_question_answer_tracker', SurveyExportManager :: APPLICATION_NAME, $condition);
  122. //option and matches of question
  123. $options = array();
  124. $matches = array();
  125. //matrix to store the answer count
  126. $answer_count = array();
  127. //reporting data and type of question
  128. $reporting_data = new ReportingData();
  129. $type = $question->get_type();
  130. switch ($type)
  131. {
  132. case SurveyMatrixQuestion :: get_type_name() :
  133. //get options and matches
  134. $opts = $question->get_options();
  135. foreach ($opts as $option)
  136. {
  137. $options[] = $option->get_value();
  138. }
  139. $matchs = $question->get_matches();
  140. foreach ($matchs as $match)
  141. {
  142. $matches[] = $match;
  143. }
  144. $total_key = count($matches);
  145. $matches[] = Translation :: get(self :: COUNT);
  146. //create answer matrix for answer counting
  147. $option_count = count($options) - 1;
  148. while ($option_count >= 0)
  149. {
  150. $match_count = count($matches) - 1;
  151. while ($match_count >= 0)
  152. {
  153. $answer_count[$option_count][$match_count] = 0;
  154. $match_count --;
  155. }
  156. // $answer_count[$option_count][$total_key] = 0;
  157. $option_count --;
  158. }
  159. //count answers from all answer trackers
  160. while ($tracker = $trackers->next_result())
  161. {
  162. $answer = $tracker->get_answer();
  163. $options_answered = array();
  164. foreach ($answer as $key => $option)
  165. {
  166. $options_answered[] = $key;
  167. $totals = array();
  168. foreach ($option as $match_key => $match)
  169. {
  170. if ($question->get_matrix_type() == SurveyMatrixQuestion :: MATRIX_TYPE_CHECKBOX)
  171. {
  172. $answer_count[$key][$match_key] ++;
  173. }
  174. else
  175. {
  176. $answer_count[$key][$match] ++;
  177. }
  178. $answer_count[$key][$total_key] ++;
  179. }
  180. }
  181. }
  182. //creating actual reporing data
  183. foreach ($matches as $match)
  184. {
  185. $reporting_data->add_row(strip_tags($match));
  186. }
  187. $totals = array();
  188. foreach ($options as $option_key => $option)
  189. {
  190. $reporting_data->add_category($option);
  191. // dump('op key: '.$option_key);
  192. // dump('option: '.$option);
  193. foreach ($matches as $match_key => $match)
  194. {
  195. // dump('match key: '.$match_key);
  196. // dump('match: '.$match);
  197. // dump('answer_count: '.$answer_count[$option_key][$match_key]);
  198. $totals[$match_key] = $totals[$match_key] + $answer_count[$option_key][$match_key];
  199. // dump('total: '.$totals[$match_key]);
  200. $reporting_data->add_data_category_row($option, strip_tags($match), $answer_count[$option_key][$match_key]);
  201. }
  202. }
  203. // dump($totals);
  204. //
  205. // dump($answer_count);
  206. // dump($totals);
  207. // exit;
  208. if (count($options) > 1)
  209. {
  210. $reporting_data->add_category(Translation :: get(self :: TOTAL));
  211. // foreach ($options as $option)
  212. // {
  213. foreach ($matches as $match_key => $match)
  214. {
  215. $reporting_data->add_data_category_row(Translation :: get(self :: TOTAL), strip_tags($match), $totals[$match_key]);
  216. }
  217. // }
  218. }
  219. break;
  220. case SurveyMultipleChoiceQuestion :: get_type_name() :
  221. //get options and matches
  222. $opts = $question->get_options();
  223. foreach ($opts as $option)
  224. {
  225. $options[] = $option->get_value();
  226. }
  227. // $options[] = self :: NO_ANSWER;
  228. $matches[] = Translation :: get(self :: COUNT);
  229. //create answer matrix for answer counting
  230. $option_count = count($options) - 1;
  231. while ($option_count >= 0)
  232. {
  233. $answer_count[$option_count] = 0;
  234. $option_count --;
  235. }
  236. // $answer_count[self :: NO_ANSWER] = 0;
  237. //count answers from all answer trackers
  238. while ($tracker = $trackers->next_result())
  239. {
  240. $answer = $tracker->get_answer();
  241. foreach ($answer as $key => $option)
  242. {
  243. if ($question->get_answer_type() == SurveyMultipleChoiceQuestion :: ANSWER_TYPE_CHECKBOX)
  244. {
  245. $answer_count[$key] ++;
  246. }
  247. else
  248. {
  249. $answer_count[$option] ++;
  250. }
  251. }
  252. }
  253. //creating actual reporing data
  254. foreach ($matches as $match)
  255. {
  256. $reporting_data->add_row(strip_tags($match));
  257. }
  258. $total = 0;
  259. foreach ($options as $option_key => $option)
  260. {
  261. $reporting_data->add_category($option);
  262. foreach ($matches as $match)
  263. {
  264. $total = $total + $answer_count[$option_key];
  265. $reporting_data->add_data_category_row($option, strip_tags($match), $answer_count[$option_key]);
  266. }
  267. }
  268. if (count($options) > 1)
  269. {
  270. $reporting_data->add_category(Translation :: get(self :: TOTAL));
  271. foreach ($matches as $match)
  272. {
  273. $reporting_data->add_data_category_row(Translation :: get(self :: TOTAL), strip_tags($match), $total);
  274. }
  275. }
  276. break;
  277. default :
  278. ;
  279. break;
  280. }
  281. return $reporting_data;
  282. }
  283. private function create_participants($ids)
  284. {
  285. $this->participants = array();
  286. $this->surveys = array();
  287. $surveys = array();
  288. foreach ($ids as $id)
  289. {
  290. $sv = array();
  291. $survey_publication = SurveyDataManager :: get_instance()->retrieve_survey_publication($id);
  292. $survey = $survey_publication->get_publication_object();
  293. $this->surveys[] = $survey;
  294. $survey_title = $survey->get_title();
  295. $survey_description = $survey->get_description();
  296. $sv[self :: SURVEY_NAME] = Utilities :: truncate_string(trim(strip_tags($survey_title)), 20, true, '');
  297. $sv[self :: SURVEY_DESCRIPTION] = Utilities :: truncate_string(trim(strip_tags($survey_description)), 20, true, '');
  298. $surveys[$id] = $sv;
  299. }
  300. $this->participants[self :: SURVEYS] = $surveys;
  301. $this->participants[self :: SURVEY_COUNT] = count($surveys);
  302. // $condition = new InCondition(SurveyPublicationGroup :: PROPERTY_SURVEY_PUBLICATION, $ids);
  303. // $publication_rel_groups = SurveyDataManager :: get_instance()->retrieve_survey_publication_groups($condition);
  304. //
  305. // $groups = array();
  306. // $group_user_ids = array();
  307. // $total_user_ids = array();
  308. // while ($publication_rel_group = $publication_rel_groups->next_result())
  309. // {
  310. // $group = GroupDataManager :: get_instance()->retrieve_group($publication_rel_group->get_group_id());
  311. // $groups[] = $group;
  312. // $group_user_ids[$group->get_id()] = $group->get_users(true, true);
  313. // $total_user_ids = array_merge($total_user_ids, $group_user_ids[$group->get_id()]);
  314. // }
  315. //
  316. // $user_ids = array();
  317. //
  318. // $condition = new InCondition(SurveyPublicationUser :: PROPERTY_SURVEY_PUBLICATION, $ids);
  319. // $publication_rel_users = SurveyDataManager :: get_instance()->retrieve_survey_publication_users($condition);
  320. while ($publication_rel_user = $publication_rel_users->next_result())
  321. {
  322. $user_ids[] = $publication_rel_user->get_user_id();
  323. }
  324. $total_user_ids = array_merge($total_user_ids, $user_ids);
  325. $total_user_ids = array_unique($total_user_ids);
  326. $conditions = array();
  327. $conditions[] = new InCondition(SurveyParticipantTracker :: PROPERTY_SURVEY_PUBLICATION_ID, $ids);
  328. $conditions[] = new InCondition(SurveyParticipantTracker :: PROPERTY_USER_ID, $total_user_ids);
  329. $condition = new AndCondition($conditions);
  330. $trackers = Tracker :: get_data('survey_participant_tracker', SurveyExportManager :: APPLICATION_NAME, $condition);
  331. $all_participants = array();
  332. $started_participants = array();
  333. $not_started_participants = array();
  334. $started_users = array();
  335. $not_started_users = array();
  336. while ($tracker = $trackers->next_result())
  337. {
  338. $all_participants[] = $tracker->get_id();
  339. switch ($tracker->get_status())
  340. {
  341. case SurveyParticipantTracker :: STATUS_NOTSTARTED :
  342. $not_started_participants[] = $tracker->get_id();
  343. $not_started_users[] = $tracker->get_user_id();
  344. break;
  345. case SurveyParticipantTracker :: STATUS_STARTED :
  346. $started_participants[] = $tracker->get_id();
  347. $started_users[] = $tracker->get_user_id();
  348. break;
  349. case SurveyParticipantTracker :: STATUS_FINISHED :
  350. $started_participants[] = $tracker->get_id();
  351. $started_users[] = $tracker->get_user_id();
  352. break;
  353. }
  354. }
  355. $this->participants[self :: ALL_PARTICIPANTS] = $all_participants;
  356. $all_participant_count = count($all_participants);
  357. $this->participants[self :: ALL_PARTICIPANT_COUNT] = $all_participant_count;
  358. $this->participants[self :: NOT_STARTED_PARTICIPANTS] = $not_started_participants;
  359. $not_started_particpant_count = count($not_started_participants);
  360. $this->participants[self :: NOT_STARTED_PARTICIPANT_COUNT] = $not_started_particpant_count;
  361. $this->participants[self :: STARTED_PARTICIPANTS] = $started_participants;
  362. $started_participant_count = count($started_participants);
  363. $this->participants[self :: STARTED_PARTICIPANT_COUNT] = $started_participant_count;
  364. $participatie = $started_participant_count / $all_participant_count * 100;
  365. $participatie = number_format($participatie, 2);
  366. $this->participants[self :: PARTICIPATION_GRADE] = $participatie;
  367. foreach ($groups as $group)
  368. {
  369. $this->participants[self :: GROUPS][$group->get_id()][self :: GROUP_NAME] = $group->get_name();
  370. $this->participants[self :: GROUPS][$group->get_id()][self :: GROUP_DESCRIPTION] = $group->get_description();
  371. $group_users = $group_user_ids[$group->get_id()];
  372. $condition = new InCondition(SurveyParticipantTracker :: PROPERTY_USER_ID, $group_users);
  373. $trackers = Tracker :: get_data('survey_participant_tracker', SurveyExportManager :: APPLICATION_NAME, $condition);
  374. $all_trackers = array();
  375. while ($tracker = $trackers->next_result())
  376. {
  377. $all_trackers[] = $tracker->get_id();
  378. }
  379. $all_tracker_count = count($all_trackers);
  380. $this->participants[self :: GROUPS][$group->get_id()][self :: ALL_PARTICIPANT_COUNT] = $all_tracker_count;
  381. $this->participants[self :: GROUPS][$group->get_id()][self :: ALL_PARTICIPANTS] = $all_trackers;
  382. $started = array_intersect($group_users, $started_users);
  383. $condition = new InCondition(SurveyParticipantTracker :: PROPERTY_USER_ID, $started);
  384. $trackers = Tracker :: get_data('survey_participant_tracker', SurveyExportManager :: APPLICATION_NAME, $condition);
  385. $started_trackers = array();
  386. while ($tracker = $trackers->next_result())
  387. {
  388. $started_trackers[] = $tracker->get_id();
  389. }
  390. $started_tracker_count = count($started_trackers);
  391. $this->participants[self :: GROUPS][$group->get_id()][self :: STARTED_PARTICIPANT_COUNT] = $started_tracker_count;
  392. $this->participants[self :: GROUPS][$group->get_id()][self :: STARTED_PARTICIPANTS] = $started_trackers;
  393. $not_started = array_intersect($group_users, $not_started_users);
  394. $condition = new InCondition(SurveyParticipantTracker :: PROPERTY_USER_ID, $not_started);
  395. $trackers = Tracker :: get_data('survey_participant_tracker', SurveyExportManager :: APPLICATION_NAME, $condition);
  396. $not_started_trackers = array();
  397. while ($tracker = $trackers->next_result())
  398. {
  399. $not_started_trackers[] = $tracker->get_id();
  400. }
  401. $this->participants[self :: GROUPS][$group->get_id()][self :: NOT_STARTED_PARTICIPANT_COUNT] = count($not_started_trackers);
  402. $this->participants[self :: GROUPS][$group->get_id()][self :: NOT_STARTED_PARTICIPANTS] = $not_started_trackers;
  403. $participatie = $started_tracker_count / $all_tracker_count * 100;
  404. $participatie = number_format($participatie, 2);
  405. $this->participants[self :: GROUPS][$group->get_id()][self :: PARTICIPATION_GRADE] = $participatie;
  406. }
  407. }
  408. }
  409. ?>