From 8c62d78b3d91e29df943047d932c70c554e18479 Mon Sep 17 00:00:00 2001 From: Angel Fernando Quiroz Campos Date: Wed, 20 Feb 2019 17:12:12 -0500 Subject: [PATCH] Add SurveyExportCsv plugin - refs BT#15280 --- plugin/surveyexportcsv/README.md | 10 + .../surveyexportcsv/SurveyExportCsvPlugin.php | 94 ++++++++ plugin/surveyexportcsv/export.php | 203 ++++++++++++++++++ plugin/surveyexportcsv/install.php | 4 + plugin/surveyexportcsv/lang/english.php | 7 + plugin/surveyexportcsv/lang/spanish.php | 7 + plugin/surveyexportcsv/plugin.php | 4 + plugin/surveyexportcsv/start.php | 50 +++++ plugin/surveyexportcsv/uninstall.php | 4 + 9 files changed, 383 insertions(+) create mode 100644 plugin/surveyexportcsv/README.md create mode 100644 plugin/surveyexportcsv/SurveyExportCsvPlugin.php create mode 100644 plugin/surveyexportcsv/export.php create mode 100644 plugin/surveyexportcsv/install.php create mode 100644 plugin/surveyexportcsv/lang/english.php create mode 100644 plugin/surveyexportcsv/lang/spanish.php create mode 100644 plugin/surveyexportcsv/plugin.php create mode 100644 plugin/surveyexportcsv/start.php create mode 100644 plugin/surveyexportcsv/uninstall.php diff --git a/plugin/surveyexportcsv/README.md b/plugin/surveyexportcsv/README.md new file mode 100644 index 00000000000..6fe7cfb6e14 --- /dev/null +++ b/plugin/surveyexportcsv/README.md @@ -0,0 +1,10 @@ +# Survey Export CSV + +Export surveys to CSV file. + +This plugin will add a new action button in survey list allowing export the survey. + +**Instructions** + +- Install plugin +- Set enabled in configuration diff --git a/plugin/surveyexportcsv/SurveyExportCsvPlugin.php b/plugin/surveyexportcsv/SurveyExportCsvPlugin.php new file mode 100644 index 00000000000..666cbb8664f --- /dev/null +++ b/plugin/surveyexportcsv/SurveyExportCsvPlugin.php @@ -0,0 +1,94 @@ + 'boolean', + ]; + + parent::__construct('0.1', 'Angel Fernando Quiroz Campos', $settings); + } + + /** + * @return SurveyExportCsvPlugin|null + */ + public static function create() + { + static $result = null; + + return $result ? $result : $result = new self(); + } + + /** + * Installation process. + */ + public function install() + { + } + + /** + * Uninstallation process. + */ + public function uninstall() + { + } + + /** + * @param $id + * + * @return string + */ + public static function filterModify($params) + { + $enabled = api_get_plugin_setting('surveyexportcsv', 'enabled'); + + if ($enabled !== 'true') { + return ''; + } + + $surveyId = isset($params['survey_id']) ? (int) $params['survey_id'] : 0; + $iconSize = isset($params['icon_size']) ? $params['icon_size'] : ICON_SIZE_SMALL; + + if (empty($surveyId)) { + return ''; + } + + return Display::url( + Display::return_icon('export_csv.png', get_lang('ExportAsCSV'), [], $iconSize), + api_get_path(WEB_PLUGIN_PATH).'surveyexportcsv/export.php?survey='.$surveyId.'&'.api_get_cidreq() + ); + } + + /** + * Create tools for all courses. + */ + private function createLinkToCourseTools() + { + $result = Database::getManager() + ->createQuery('SELECT c.id FROM ChamiloCoreBundle:Course c') + ->getResult(); + + foreach ($result as $item) { + $this->createLinkToCourseTool($this->get_name().':teacher', $item['id'], 'survey.png'); + } + } + + /** + * Remove all course tools created by plugin. + */ + private function removeLinkToCourseTools() + { + Database::getManager() + ->createQuery('DELETE FROM ChamiloCourseBundle:CTool t WHERE t.link LIKE :link AND t.category = :category') + ->execute(['link' => 'surveyexportcsv/start.php%', 'category' => 'plugin']); + } +} diff --git a/plugin/surveyexportcsv/export.php b/plugin/surveyexportcsv/export.php new file mode 100644 index 00000000000..d51253e70b5 --- /dev/null +++ b/plugin/surveyexportcsv/export.php @@ -0,0 +1,203 @@ +get('enabled') !== 'true') { + api_not_allowed(true); +} + +$questionsData = SurveyManager::get_questions($surveyId, $courseId); +// Sort questions by their "sort" field +$questionsData = array_filter( + $questionsData, + function ($questionData) { + return in_array($questionData['type'], ['yesno', 'multiplechoice', 'open']); + } +); +usort( + $questionsData, + function ($qL, $qR) { + if ($qL['sort'] == $qR['sort']) { + return 0; + } + + return $qL['sort'] < $qR['sort'] ? -1 : 1; + } +); + +$content = []; +$content[] = firstRow($questionsData); + +$surveyAnswers = getSurveyAnswers($courseId, $surveyId); + +// Process answers +foreach ($surveyAnswers as $i => $answer) { + $row = otherRow($questionsData, $answer['user'], $courseId); + array_unshift($row, $i + 1); + + $content[] = $row; +} + +// Generate file +$fileName = md5($surveyId.time()); + +Export::arrayToCsv($content, $fileName); + +/** + * Generate the first row for file + * + * @param $questions + * + * @return array + */ +function firstRow($questions) +{ + array_pop($questions); + $positions = array_keys($questions); + + $row = ['DATID']; + + foreach ($positions as $position) { + $row[] = sprintf("P%02d", $position + 1); + } + + $row[] = 'DATOBS'; + + return $row; +} + +/** + * Get unique answer for surveys by users + * + * @param int $courseId + * @param int $surveyId + * + * @return array + */ +function getSurveyAnswers($courseId, $surveyId) +{ + $surveyAnswers = Database::getManager() + ->createQuery( + 'SELECT sa.user, MIN(sa.iid) AS id FROM ChamiloCourseBundle:CSurveyAnswer sa + WHERE sa.cId = :course AND sa.surveyId = :survey + GROUP BY sa.user ORDER BY id ASC' + ) + ->setParameters(['course' => $courseId, 'survey' => $surveyId]) + ->getResult(); + + return $surveyAnswers; +} + +/** + * @param string $user + * @param int $courseId + * @param int $surveyId + * @param int $questionId + * + * @return array + */ +function getQuestionOptions($user, $courseId, $surveyId, $questionId) +{ + $options = Database::getManager() + ->createQuery( + 'SELECT sqo FROM ChamiloCourseBundle:CSurveyQuestionOption sqo + INNER JOIN ChamiloCourseBundle:CSurveyAnswer sa + WITH + sqo.cId = sa.cId + AND sqo.questionId = sa.questionId + AND sqo.surveyId = sa.surveyId + AND sqo.iid = sa.optionId + WHERE sa.user = :user AND sa.cId = :course AND sa.surveyId = :survey AND sa.questionId = :question' + ) + ->setParameters( + [ + 'user' => $user, + 'course' => $courseId, + 'survey' => $surveyId, + 'question' => $questionId, + ] + ) + ->getResult(); + + return $options; +} + +/** + * @param int $questionId + * @param int $surveyId + * @param int $courseId + * @param string $user + * + * @throws \Doctrine\ORM\NonUniqueResultException + * + * @return CSurveyAnswer|null + */ +function getOpenAnswer($questionId, $surveyId, $courseId, $user) +{ + $answer = Database::getManager() + ->createQuery( + 'SELECT sa FROM ChamiloCourseBundle:CSurveyAnswer sa + WHERE sa.cId = :course AND sa.surveyId = :survey AND sa.questionId = :question AND sa.user = :user' + ) + ->setParameters(['course' => $courseId, 'survey' => $surveyId, 'question' => $questionId, 'user' => $user]) + ->getOneOrNullResult(); + + return $answer; +} + +/** + * Generate the content rows for file + * + * @param array $questions + * @param string $user + * @param int $courseId + * + * @throws \Doctrine\ORM\NonUniqueResultException + * + * @return array + */ +function otherRow($questions, $user, $courseId) +{ + $row = []; + + foreach ($questions as $question) { + if ('open' === $question['type']) { + $answer = getOpenAnswer($question['question_id'], $question['survey_id'], $courseId, $user); + + $row[] = Security::remove_XSS( + $answer->getOptionId() + ); + } else { + $options = getQuestionOptions( + $user, + $courseId, + $question['survey_id'], + $question['question_id'] + ); + + /** @var CSurveyQuestionOption $option */ + foreach ($options as $option) { + $row[] = $option->getSort(); + } + } + } + + return $row; +} diff --git a/plugin/surveyexportcsv/install.php b/plugin/surveyexportcsv/install.php new file mode 100644 index 00000000000..f747870af76 --- /dev/null +++ b/plugin/surveyexportcsv/install.php @@ -0,0 +1,4 @@ +install(); diff --git a/plugin/surveyexportcsv/lang/english.php b/plugin/surveyexportcsv/lang/english.php new file mode 100644 index 00000000000..c47019a3712 --- /dev/null +++ b/plugin/surveyexportcsv/lang/english.php @@ -0,0 +1,7 @@ +get_info(); diff --git a/plugin/surveyexportcsv/start.php b/plugin/surveyexportcsv/start.php new file mode 100644 index 00000000000..abd27bc52fc --- /dev/null +++ b/plugin/surveyexportcsv/start.php @@ -0,0 +1,50 @@ +set_additional_parameters(['cidReq' => $courseCode]); +$table->set_header(0, '', false); +$table->setHideColumn(0); +$table->set_header(1, get_lang('SurveyName')); +$table->set_header(2, get_lang('SurveyCode'), true, ['class' => 'text-center'], ['class' => 'text-center']); +$table->set_header(3, get_lang('NumberOfQuestions'), true, ['class' => 'text-right'], ['class' => 'text-right']); +$table->set_header(4, get_lang('Author')); +$table->set_header(5, get_lang('AvailableFrom'), true, ['class' => 'text-center'], ['class' => 'text-center']); +$table->set_header(6, get_lang('AvailableUntil'), true, ['class' => 'text-center'], ['class' => 'text-center']); +$table->set_header(7, get_lang('Invite'), true, ['class' => 'text-right'], ['class' => 'text-right']); +$table->set_header(8, get_lang('Anonymous'), true, ['class' => 'text-center'], ['class' => 'text-center']); +$table->set_column_filter(8, ['SurveyUtil', 'anonymous_filter']); + +if (api_get_configuration_value('allow_mandatory_survey')) { + $table->set_header(9, get_lang('IsMandatory'), true, ['class' => 'text-center'], ['class' => 'text-center']); + $table->set_header(10, get_lang('Export'), false, ['class' => 'text-center'], ['class' => 'text-center']); + $table->set_column_filter(10, ['SurveyExportCsvPlugin', 'filterModify']); +} else { + $table->set_header(9, get_lang('Export'), false, ['class' => 'text-center'], ['class' => 'text-center']); + $table->set_column_filter(9, ['SurveyExportCsvPlugin', 'filterModify']); +} + +$pageTitle = $plugin->get_title(); + +$template = new Template($pageTitle); + +$content = $table->return_table(); + +$template->assign('header', $pageTitle); +$template->assign('content', $content); +$template->display_one_col_template(); diff --git a/plugin/surveyexportcsv/uninstall.php b/plugin/surveyexportcsv/uninstall.php new file mode 100644 index 00000000000..bf33c03d5a6 --- /dev/null +++ b/plugin/surveyexportcsv/uninstall.php @@ -0,0 +1,4 @@ +uninstall();