From e9361a484bbd69bb508ac2f996831d43eb0fad8d Mon Sep 17 00:00:00 2001 From: Michal Chruscielski Date: Tue, 22 Oct 2024 20:12:21 +0200 Subject: [PATCH] question-export command --- .../Moodle41/Question/QuestionExport.php | 105 ++++++++++++++++++ moosh-questions-export | 1 + moosh-questions-export.json | 1 + www/commands/index.md | 21 ++++ 4 files changed, 128 insertions(+) create mode 100644 Moosh/Command/Moodle41/Question/QuestionExport.php create mode 100644 moosh-questions-export create mode 100644 moosh-questions-export.json diff --git a/Moosh/Command/Moodle41/Question/QuestionExport.php b/Moosh/Command/Moodle41/Question/QuestionExport.php new file mode 100644 index 00000000..5f35912c --- /dev/null +++ b/Moosh/Command/Moodle41/Question/QuestionExport.php @@ -0,0 +1,105 @@ +addOption('c|course:', 'Specifies questions course id.'); + $this->addOption('f|filename:', 'Specifies exported file name.', 'moosh-questions-export'); + $this->addOption('C|category:', 'Specifies questions category id.'); + } + + public function execute() { + global $DB, $CFG; + + $courseId = $this->expandedOptions['course']; + $categoryId = $this->expandedOptions['category']; + $fileName = $this->expandedOptions['filename']; + + // moodle queries questions using similar requests, it is needed due to complicated structure + $sql = " + SELECT q.id AS id, q.name AS name, qc.id AS categoryId, q.questiontext as text + FROM {question} q + JOIN {question_versions} qv ON q.id = qv.questionid + JOIN {question_bank_entries} qbe ON qv.questionbankentryid = qbe.id + JOIN {question_categories} qc ON qbe.questioncategoryid = qc.id + JOIN {context} ctx ON qc.contextid = ctx.id + JOIN {course} c ON ctx.instanceid = c.id + WHERE (qc.id = '$categoryId' or '$categoryId' = '') + and (c.id = '$courseId' or '$courseId' = '') + "; + + $questions = $DB->get_records_sql($sql); + + if(!string_ends_with($fileName, ".json")) { + $fileName = $fileName . ".json"; + } + + $fullQuestions = $this->loadAnswers($questions); + + $json = json_encode($fullQuestions); + + file_put_contents($fileName, $json); + } + + /** + * Loads answer for question array and returns it. + * @param stdClass[] $questions + * @return stdClass[] + */ + public function loadAnswers($questions) { + global $DB; + + $questionsWithAnswers = array(); + + foreach ($questions as $question) { + $correctAnswer = $DB->get_record('question_answers', array('question' => $question->id, 'fraction' => 1.0)); + $question->answer = $correctAnswer->answer; + + $questionsWithAnswers[] = $this->formatQuestion($question); + } + + return $questionsWithAnswers; + } + + /** + * Removes html tags from question text and answer + * @param \stdClass $question + * @return \stdClass + */ + public function formatQuestion($question) { + $question->text = $this->stripAndTrim($question->text); + $question->answer = $this->stripAndTrim($question->answer); + + return $question; + } + + /** + * Strips html from string and trims it. If null given returns null. + * @param string $string + * @return null|string + */ + public function stripAndTrim($string) { + if(isset($string)) { + $string = trim(strip_tags($string)); + } + + return $string; + } + +} diff --git a/moosh-questions-export b/moosh-questions-export new file mode 100644 index 00000000..71df7043 --- /dev/null +++ b/moosh-questions-export @@ -0,0 +1 @@ +{"1":{"id":"1","parent":"0","name":"Question 1","questiontext":"

WOOOO?<\/p>","questiontextformat":"1","generalfeedback":"","generalfeedbackformat":"1","defaultmark":"1.0000000","penalty":"1.0000000","qtype":"truefalse","length":"1","stamp":"localhost+240828104454+yH83pv","timecreated":"1724841894","timemodified":"1724841894","createdby":"2","modifiedby":"2"},"2":{"id":"2","parent":"0","name":"My quest","questiontext":"

ion hey<\/p>","questiontextformat":"1","generalfeedback":"","generalfeedbackformat":"1","defaultmark":"1.0000000","penalty":"0.3333333","qtype":"multichoice","length":"1","stamp":"localhost+241022094604+DiUHA8","timecreated":"1729590364","timemodified":"1729590364","createdby":"2","modifiedby":"2"}} \ No newline at end of file diff --git a/moosh-questions-export.json b/moosh-questions-export.json new file mode 100644 index 00000000..2acc25ff --- /dev/null +++ b/moosh-questions-export.json @@ -0,0 +1 @@ +[{"id":"1","name":"Question 1","categoryid":"3","text":"WOOOO?","answer":"False"},{"id":"2","name":"My quest","categoryid":"8","text":"ion hey","answer":"My ans"}] \ No newline at end of file diff --git a/www/commands/index.md b/www/commands/index.md index 154e36f4..4df359c7 100755 --- a/www/commands/index.md +++ b/www/commands/index.md @@ -2065,6 +2065,27 @@ Example: moosh plugin-uninstall theme_elegance +question-export +--------------- + +Exports all or selected questions. + +Parameters + +| Option | Description | +|----------------|-----------------------------------------------| +| -C, --category | Questions category id. | +| -c, --course | Questions course id. | +| -f, --filename | Exported file name or path without extension. | + +Example: export all questions + + moosh question-export + +Example: export questions with category with id 3 to file my-questions.json + + moosh question-export -C 3 -f my-questions + question-import ---------------