diff --git a/README.md b/README.md index 05a4f0b2..4c41cf45 100644 --- a/README.md +++ b/README.md @@ -83,155 +83,31 @@ input you can evaluate your answer (in self assessment mode) or move to the next Version History =============== +* The stable version 3.1.x for **ILIAS 5.4** with new feedback styles is found in the Github branch **master-ilias54** * The stable version 3.0.x for **ILIAS 5.3** with new functionalities from STACK such a new input types is found in the Github branch **master-ilias53** * The stable version 2.4.x for **ILIAS 5.2 to 5.3** is found in the GitHub branch **master-ilias52** * The stable version 2.3.x for **ILIAS 5.0 to 5.1** is found in the GitHub branch **master** -Update from Version 2.x ------------------------ -After updating the code files of the plugin, the update is started in the plugin administration of ILIAS. -All STACK questions of your platform will be translated to the new syntax for CAS text in STACK (use of {@..@} instead of @...@) -This change is automatically done in the plugin update, but we recommend to check the questions before use it in tests. - -PLEASE BACKUP YOUR DATABASE before you run the update from an older version. Depending on the number of questions, the update takes some minutes, please set the PHP variable max_execution_time high enough. - -The translation is also done when importing questions from ILIAS or MoodleXML, but please notice that this conversion is one way.You can import "old CASText behaviour" questions to a platform with STACK plugin version 3.0+. -But if you import "new CASText behaviour" questions to a platform with a previous version of the plugin, your question will not be properly shown on that platform. - -Version 3.0.22 (2019-05-03) for ILIAS 5.3 ----------------------------------------- -The following bug reports were fixed: -- https://mantis.ilias.de/view.php?id=22847 About validation in equivalence inputs -- https://mantis.ilias.de/view.php?id=24640 About model answer being variables which are a set of numbers. -- https://mantis.ilias.de/view.php?id=24998 About not showing best solution properly when best solution is 0. -- Partial solution for https://mantis.ilias.de/view.php?id=24273 for Algebraic inputs. Not solved for other question types. -- https://mantis.ilias.de/view.php?id=24835 About matrix brackets -- https://mantis.ilias.de/view.php?id=25256 About user input not shown in validation or test results - -Version 3.0.20 (2019-04-03) for ILIAS 5.3 ----------------------------------------- -The following bug reports were fixed: -- https://mantis.ilias.de/view.php?id=24998 - -Version 3.0.17 (2019-03-13) for ILIAS 5.3 ------------------------------------------ -- Configuration of multiple MaximaPool servers for different purposes (Authoring, Test Run) - -Version 3.0.16 (2019-02-27) for ILIAS 5.3 ------------------------------------------ -- Added a new feature Copy of Nodes and PRT: In question Authoring now exists the option to copy nodes and PRT, when clicking on copying Node or PRT, the chosen element is stored in the session, then, the user should go to the question or PRT the user wants to paste te node/prt and click on paste. A new PRT or a new node will be created with the values of the copied one. Please notice that when a node is copied to a PRT, the fields next node when true/false are not copied and should be edited by hand. -The following bug reports were fixed: -- https://mantis.ilias.de/view.php?id=24835 about matrix brackets - -Version 3.0.12 (2018-11-30) for ILIAS 5.3 +Version 3.1.1 (2019-06-24) for ILIAS 5.4 ---------------------------------------- -- Solved some problems with best solution display when question variables are used in model answer in algebraic inputs. -- Solved some problems with Matrix display in best solution -The following bug reports were fixed: -- https://mantis.ilias.de/view.php?id=23977 -- https://mantis.ilias.de/view.php?id=23895 about syntax hints +This version includes the changes needed to run STACK questions in ILIAS 5.4. +* A new feature has been included: Feedback Styles, that can be managed through plugin configuration and Layout and Styles / Content styles. You can use your own content style for STACK feedback, In plugin configuration there is a new tab under General Settings / Feedback Styles Settings where settings for this new feature can be found. -Version 3.0.11 (2018-11-26) for ILIAS 5.3 ----------------------------------------- -- Solved problems to establish default values for options, inputs and PRT, now all already present default values works properly. -- Added the following default values to plugin configuration: Options: Matrix Parenthesis, Inputs: Syntax hint, Forbidden word, allowed words, show validation (as dropdown) and extra options for inputs, PRT: Simplification, First node of predefined PRT: Answertest, test options, quiet feedback, and mode, score, penalty and answernote for both positive and negative branch. -- Added TinyMCE editor for default feedback in configuration/options. -- Some text changes has been made in the german language. -The following bug report were fixed: -- https://mantis.ilias.de/view.php?id=24003 about missing translation to german. -- https://mantis.ilias.de/view.php?id=23913 about grammatical error in german -- https://mantis.ilias.de/view.php?id=24121 about missing display of best solution - -Version 3.0.10 (2018-10-24) for ILIAS 5.3 ----------------------------------------- -Validation button is now directly attached to the input for algebraic inputs, instead of having an space between them. -Validation buttons now doesn´t use the bootstrap style. -Some minor changes has been made, and the following bugs has been solved. -- https://mantis.ilias.de/view.php?id=23753 about checking the user response in the code. -- https://mantis.ilias.de/view.php?id=23314 about info messages -- https://mantis.ilias.de/view.php?id=23533 about validation of string inputs -- https://mantis.ilias.de/view.php?id=23414 about testcases - -Version 3.0.9 (2018-10-10) for ILIAS 5.3 +Version 3.1.2 (2019-07-01) for ILIAS 5.4 ---------------------------------------- -Validation button is now displayed as a small "check" button, and is always displayed next to the input it belongs. -Some minor bugs has been solved in this version, please use https://mantis.ilias.de to report bugs. +The following bugs have been solved: +- https://mantis.ilias.de/view.php?id=25256 About validation of matrix inputs after checking results in preview mode. +- https://mantis.ilias.de/view.php?id=25290 About default values for PRT and Nodes not working properly in non-new questions. -Version 3.0.8 (2018-09-07) for ILIAS 5.3 +Version 3.1.3 (2019-07-31) for ILIAS 5.4 ---------------------------------------- -Inputs representation in validation and best solution now takes the minimal size as possible, depending on user or teacher input, and it´s displayed as code text, instead of repeating the input again - -Version 3.0.7 (2018-09-03) for ILIAS 5.3 ----------------------------------------- -Some important changes has been made to question view, either in preview, test mode or printview, the main goal of this changes is to fulfill the needs of SIG Mathe+ILIAS in terms of going back to previous 5.2 style of inputs presentation -- All inputs which can be validated got the validation view changed to a disabled input or textarea filled in with the user solution on the left side, and the validation feedback on the right side. -- Validation messages are now displayed with a white background in order to distinct it from question text. -- The behaviour of inputs presentation in best solution in aligned to validation, instead of showing only a message saying "a possible solution is..." a disabled input is presented filled in with the model answer, All these inputs have the same format as the question input. -Some minor bugs has been solved in this version, please use https://mantis.ilias.de to report bugs. - -Version 3.0.6 (2018-06-25) for ILIAS 5.3 ----------------------------------------- -Some index has been created in the DB, in order to improve performance. -Some code changes were made in order to allow STACK questions run in Learning modules through PCPluginQuestion plugin. -Some bugfix were made on this version: -- https://www.ilias.de/mantis/view.php?id=23135 About showing validation in dropdown, checkbox and radiobutton inputs -- https://www.ilias.de/mantis/view.php?id=22900 About showing validation after question has been evaluated -- https://www.ilias.de/mantis/view.php?id=22655 About error messages shown in wrong places. -- https://www.ilias.de/mantis/view.php?id=22954 About missing german text in units questions. -- https://www.ilias.de/mantis/view.php?id=23237 About problem when updating to 3.0 with prt feedback. - -Version 3.0.5 (2018-05-28) for ILIAS 5.3 ----------------------------------------- -Some bugfix were made on this version: -- https://www.ilias.de/mantis/view.php?id=22847 About validation in new input types -- https://www.ilias.de/mantis/view.php?id=22969 About validation options -- https://www.ilias.de/mantis/view.php?id=23016 About equivalence input firstline option -- https://www.ilias.de/mantis/view.php?id=22900 about showing validation. - -Version 3.0.4 (2018-04-26) for ILIAS 5.3 ----------------------------------------- -Some bugfix were made on this version: -- https://www.ilias.de/mantis/view.php?id=22945 About space between checkboxes and radiobuttons and texts -- https://www.ilias.de/mantis/view.php?id=22938 About problems installing the plugin in a fresh 5.3 client -- https://www.ilias.de/mantis/view.php?id=22925 About answertests names in german missing -- https://www.ilias.de/mantis/view.php?id=22912 About german text file -- https://www.ilias.de/mantis/view.php?id=22946 About validation in equivalence inputs -- https://www.ilias.de/mantis/view.php?id=22947 About syntax hint in equivalence inputs -- https://www.ilias.de/mantis/view.php?id=22847 About validation in equivalence inputs -- Some other minor changes. - -Version 3.0.3 (2018-04-05) for ILIAS 5.3 ----------------------------------------- -Some bugfix were made on this version: -- https://www.ilias.de/mantis/view.php?id=22795 About Deployed seeds navigation -- https://www.ilias.de/mantis/view.php?id=22782 About testcases - +Some small changes has been made in language variables +Now all feedback Types are always displayed in the authoring interface also if no content style has been chosen in the plugin configuration. -Version 3.0.2 (2018-03-28) for ILIAS 5.3 +Version 3.1.4 (2019-08-23) for ILIAS 5.4 ---------------------------------------- -Some bugfix were made on this version: -- https://www.ilias.de/mantis/view.php?id=22780 regarding br before inputs -- https://www.ilias.de/mantis/view.php?id=22779 about HTML in version 3.0 +This version includes support for PHP 7.2 in ILIAS 5.4 platform, during the process of update this plugin some ILIAS core bugs were found (e.g. importing question pools), those non-STACk related bugs can make the experience of using the plugin in a PHP 7.2 installation not smooth as intended, if you find any bugs in a PHP 7.2 platform, please report it in Mantis. -Version 3.0.0 (2018-03-07) for ILIAS 5.3 +Version 3.1.5 (2019-08-26) for ILIAS 5.4 ---------------------------------------- -This is a major update. It uses the core classes from STACK version 4.0, the sample questions have also be changed. Please read the section "Update from version 2.x". - -NEW FEATURES: -- 8 new input types (We highly recommend to read the Documentation of all new input types that can be found here: https://stack2.maths.ed.ac.uk/demo/question/type/stack/doc/doc.php/Authoring/Inputs.md): - - Numerical input: - This input type requires the student to type in a number of some kind. Any expression with a variable will be rejected as invalid. - - Scientific units input: - The support for scientific units includes an input type which enables teachers to check units as valid/invalid. - - Equivalence reasoning input: - The purpose of this input type is to enable students to work line by line and reason by equivalence. Note, the teacher's answer and any syntax hint must be a list! If you just pass in an expression strange behaviour may result. - - Dropdown/Checkbox/Radio: - The dropdown, checkbox and radio input types enable teachers to create multiple choice questions. - - String input: - This is a normal input into which students may type whatever they choose. It is always converted into a Maxima string internally. Note that there is no way whatsoever to parse the student's string into a Maxima expression. If you accept a string, then it will always remain a string! You can't later check for algebraic equivalence, the only tests available will be simple string matches, regular expressions etc - - Notes input - This input is a text area into which students may type whatever they choose. It can be used to gather their notes or "working". However, this input always returns an empty value to the CAS, so that the contents are never assessed. - - CASText now supports conditional statements and adaptive blocks. - - Healthcheck has been rebuilt, now shows more information about the CAS connection and the Maxima version used. - - Maxima Libraries can be added to maximalocal from plugin configuration (Notice that this feature doesn't work with server configuration) - +Some bugs in PHP 7.2 installations has been solved. \ No newline at end of file diff --git a/classes/GUI/question_authoring/class.assStackQuestionAuthoringGUI.php b/classes/GUI/question_authoring/class.assStackQuestionAuthoringGUI.php index d30f22e4..4e38a53b 100644 --- a/classes/GUI/question_authoring/class.assStackQuestionAuthoringGUI.php +++ b/classes/GUI/question_authoring/class.assStackQuestionAuthoringGUI.php @@ -113,6 +113,10 @@ public function showAuthoringPanel() $this->getPlugin()->includeClass('utils/FormProperties/class.ilTabsFormPropertyGUI.php'); $this->getPlugin()->includeClass('utils/FormProperties/class.ilButtonFormPropertyGUI.php'); + //https://mantis.ilias.de/view.php?id=25290 + require_once('./Customizing/global/plugins/Modules/TestQuestionPool/Questions/assStackQuestion/classes/model/configuration/class.assStackQuestionConfig.php'); + $this->default = assStackQuestionConfig::_getStoredSettings("all"); + //Add general properties to form like question text, title, author... //ADD predefined input and validation fields if ($this->getQuestionGUI()->object->getQuestion() == "") @@ -120,8 +124,6 @@ public function showAuthoringPanel() $this->new_question = TRUE; $this->getQuestionGUI()->object->setQuestion("[[input:ans1]] [[validation:ans1]]"); $this->getQuestionGUI()->object->setPoints("1"); - require_once('./Customizing/global/plugins/Modules/TestQuestionPool/Questions/assStackQuestion/classes/model/configuration/class.assStackQuestionConfig.php'); - $this->default = assStackQuestionConfig::_getStoredSettings("all"); } //Add question title when blank @@ -227,7 +229,7 @@ public function addInputs() $inputs_section_header->setTitle($this->getPlugin()->txt('inputs')); $this->getForm()->addItem($inputs_section_header); - if (sizeof($this->getQuestionGUI()->object->getInputs())) + if (!empty($this->getQuestionGUI()->object->getInputs())) { //In case of edition foreach ($this->getQuestionGUI()->object->getInputs() as $input_name => $input) @@ -254,7 +256,7 @@ public function addPRTs() { $prts = new ilTabsFormPropertyGUI($this->getPlugin()->txt('prts'), "question_prts", 12, FALSE); - if (sizeof($this->getQuestionGUI()->object->getPotentialResponsesTrees())) + if (!empty($this->getQuestionGUI()->object->getPotentialResponsesTrees())) { foreach ($this->getQuestionGUI()->object->getPotentialResponsesTrees() as $prt_name => $prt) { @@ -268,9 +270,25 @@ public function addPRTs() $new_prt = new assStackQuestionPRT(-1, $this->getQuestionGUI()->object->getId()); $new_prt->setPRTName('new_prt'); $new_prt->setPRTValue(1); + //https://mantis.ilias.de/view.php?id=25290 + $new_prt->setAutoSimplify($this->default["prt_simplify"]); $new_prt->checkPRT(TRUE); + //https://mantis.ilias.de/view.php?id=25290 $new_prt_node = new assStackQuestionPRTNode(-1, $this->getQuestionGUI()->object->getId(), 'new_prt', '0', -1, -1); + $new_prt_node->setAnswerTest($this->default["prt_node_answer_test"]); + $new_prt_node->setQuiet($this->default["prt_node_quiet"]); + $new_prt_node->setTestOptions($this->default["prt_node_options"]); + + $new_prt_node->setTrueScoreMode($this->default["prt_pos_mod"]); + $new_prt_node->setFalseScoreMode($this->default["prt_neg_mod"]); + + $new_prt_node->setTrueScore($this->default["prt_pos_score"]); + $new_prt_node->setFalseScore($this->default["prt_neg_score"]); + + $new_prt_node->setTruePenalty($this->default["prt_pos_penalty"]); + $new_prt_node->setFalsePenalty($this->default["prt_neg_penalty"]); + $new_prt_node->checkPRTNode(TRUE); $new_prt->setPRTNodes(array('0' => $new_prt_node)); $new_prt->setFirstNodeName($new_prt->getFirstNodeName(TRUE)); @@ -737,7 +755,7 @@ public function getNodesPart(assStackQuestionPRT $prt, $container_width = "") $nodes = new ilTabsFormPropertyGUI($this->getPlugin()->txt('prt_nodes'), 'prt_' . $prt->getPRTName() . '_nodes', $container_width, FALSE); $q_nodes = $prt->getPRTNodes(); - if (sizeof($q_nodes)) + if (!empty($q_nodes)) { foreach ($q_nodes as $node) { @@ -750,7 +768,7 @@ public function getNodesPart(assStackQuestionPRT $prt, $container_width = "") } } //Add tab per node in the current PRT - if (sizeof($q_nodes)) + if (!empty($q_nodes)) { foreach ($q_nodes as $node) { @@ -764,6 +782,20 @@ public function getNodesPart(assStackQuestionPRT $prt, $container_width = "") if ($prt->getPRTName() != 'new_prt') { $new_prt_node = new assStackQuestionPRTNode(-1, $this->getQuestionGUI()->object->getId(), $prt->getPRTName(), $prt->getPRTName() . '_new_node', -1, -1); + //https://mantis.ilias.de/view.php?id=25290 + $new_prt_node->setAnswerTest($this->default["prt_node_answer_test"]); + $new_prt_node->setQuiet($this->default["prt_node_quiet"]); + $new_prt_node->setTestOptions($this->default["prt_node_options"]); + + $new_prt_node->setTrueScoreMode($this->default["prt_pos_mod"]); + $new_prt_node->setFalseScoreMode($this->default["prt_neg_mod"]); + + $new_prt_node->setTrueScore($this->default["prt_pos_score"]); + $new_prt_node->setFalseScore($this->default["prt_neg_score"]); + + $new_prt_node->setTruePenalty($this->default["prt_pos_penalty"]); + $new_prt_node->setFalsePenalty($this->default["prt_neg_penalty"]); + $new_prt_node->checkPRTNode(TRUE); $new_node_part = $this->getNodePart($prt, $new_prt_node); $new_node_part->setTitle($this->getPlugin()->txt('add_new_node')); @@ -949,6 +981,9 @@ public function getNodePositivePart(assStackQuestionPRT $prt, assStackQuestionPR $node_pos_specific_feedback_info_text .= $this->addInfoTooltip("cas_text"); $node_pos_specific_feedback->setInfo($node_pos_specific_feedback_info_text); + $node_pos_feedback_class = new ilSelectInputGUI($this->getPlugin()->txt('prt_node_pos_feedback_class'), 'prt_' . $prt->getPRTName() . '_node_' . $node->getNodeName() . '_pos_feedback_class'); + $node_pos_feedback_class->setOptions($this->getFeedbackOptions()); + $node_pos_feedback_class->setInfo($this->getPlugin()->txt('prt_node_pos_feedback_class_info')); $this->getQuestionGUI()->setRTESupport($node_pos_specific_feedback); @@ -961,6 +996,7 @@ public function getNodePositivePart(assStackQuestionPRT $prt, assStackQuestionPR //$node_pos_next_node->setValue($this->default[""]); $node_pos_answernote->setValue($this->default["prt_pos_answernote"]); //$node_pos_specific_feedback->setValue($this->default[""]); + $node_pos_feedback_class->setValue(1); } else { $node_pos_mode->setValue($node->getTrueScoreMode()); @@ -969,6 +1005,7 @@ public function getNodePositivePart(assStackQuestionPRT $prt, assStackQuestionPR $node_pos_next_node->setValue($node->getTrueNextNode()); $node_pos_answernote->setValue($node->getTrueAnswerNote()); $node_pos_specific_feedback->setValue($node->getTrueFeedback()); + $node_pos_feedback_class->setValue($node->getTrueFeedbackFormat()); } @@ -982,6 +1019,7 @@ public function getNodePositivePart(assStackQuestionPRT $prt, assStackQuestionPR } $positive_part->addFormProperty($node_pos_answernote); $positive_part->addFormProperty($node_pos_specific_feedback); + $positive_part->addFormProperty($node_pos_feedback_class); return $positive_part; } @@ -1031,6 +1069,9 @@ public function getNodeNegativePart(assStackQuestionPRT $prt, assStackQuestionPR $node_neg_specific_feedback_info_text .= $this->addInfoTooltip("cas_text"); $node_neg_specific_feedback->setInfo($node_neg_specific_feedback_info_text); + $node_neg_feedback_class = new ilSelectInputGUI($this->getPlugin()->txt('prt_node_neg_feedback_class'), 'prt_' . $prt->getPRTName() . '_node_' . $node->getNodeName() . '_neg_feedback_class'); + $node_neg_feedback_class->setOptions($this->getFeedbackOptions()); + $node_neg_feedback_class->setInfo($this->getPlugin()->txt('prt_node_neg_feedback_class_info')); $this->getQuestionGUI()->setRTESupport($node_neg_specific_feedback); @@ -1043,6 +1084,7 @@ public function getNodeNegativePart(assStackQuestionPRT $prt, assStackQuestionPR //$node_neg_next_node->setValue($this->default[""]); $node_neg_answernote->setValue($this->default["prt_neg_answernote"]); //$node_neg_specific_feedback->setValue($this->default[""]); + $node_neg_feedback_class->setValue(1); } else { $node_neg_mode->setValue($node->getFalseScoreMode()); @@ -1051,6 +1093,7 @@ public function getNodeNegativePart(assStackQuestionPRT $prt, assStackQuestionPR $node_neg_next_node->setValue($node->getFalseNextNode()); $node_neg_answernote->setValue($node->getFalseAnswerNote()); $node_neg_specific_feedback->setValue($node->getFalseFeedback()); + $node_neg_feedback_class->setValue($node->getFalseFeedbackFormat()); } //Add properties to form @@ -1063,6 +1106,8 @@ public function getNodeNegativePart(assStackQuestionPRT $prt, assStackQuestionPR } $negative_part->addFormProperty($node_neg_answernote); $negative_part->addFormProperty($node_neg_specific_feedback); + $negative_part->addFormProperty($node_neg_feedback_class); + return $negative_part; } @@ -1076,11 +1121,14 @@ public function manageErrorMessages() $session_error_message = ""; $session_info_message = ""; - if (sizeof($_SESSION["stack_authoring_errors"][$this->getQuestionGUI()->object->getId()])) + if (isset($_SESSION["stack_authoring_errors"][$this->getQuestionGUI()->object->getId()])) { - foreach ($_SESSION["stack_authoring_errors"][$this->getQuestionGUI()->object->getId()] as $session_error) + if (!empty($_SESSION["stack_authoring_errors"][$this->getQuestionGUI()->object->getId()])) { - $session_error_message .= $session_error . "
"; + foreach ($_SESSION["stack_authoring_errors"][$this->getQuestionGUI()->object->getId()] as $session_error) + { + $session_error_message .= $session_error . "
"; + } } } @@ -1194,4 +1242,28 @@ public function getTemplate() return $this->template; } + public function getFeedbackOptions() + { + global $DIC; + $lng = $DIC->language(); + $options = array(); + + //Add default option + + /* + * AS WE ARE USING THE TRUE/FALSE FEEDBACK FORMAT FIELD OF THE DATABASE + * WHICH IS NOT USED AT THE MOMENT, AND IS ALWAYS 0 OR 1. WE HAVE TO + * DEFINE VALUES FOR EACH OF THE FEEDBACK STYLES, BEGINNING BY 2, TO DISTINGUISH + * QUESTION WHICH USES THIS STYLES AND THOSE WHICH NOT. + */ + + $options[1] = $lng->txt("default"); + $options[2] = $this->getPlugin()->txt("feedback_node_right"); + $options[3] = $this->getPlugin()->txt("feedback_node_wrong"); + $options[4] = $this->getPlugin()->txt("feedback_solution_hint"); + $options[5] = $this->getPlugin()->txt("feedback_extra_info"); + $options[6] = $this->getPlugin()->txt("feedback_plot_feedback"); + + return $options; + } } \ No newline at end of file diff --git a/classes/GUI/question_authoring/class.assStackQuestionDeployedSeedsGUI.php b/classes/GUI/question_authoring/class.assStackQuestionDeployedSeedsGUI.php index 1cebfb06..136413dd 100644 --- a/classes/GUI/question_authoring/class.assStackQuestionDeployedSeedsGUI.php +++ b/classes/GUI/question_authoring/class.assStackQuestionDeployedSeedsGUI.php @@ -98,7 +98,7 @@ private function getQuestionNotesForSeeds() $q_note = $deployed_seed->getQuestionNote(); $include = TRUE; - if (sizeof($valid_seeds)) + if (!empty($valid_seeds)) { foreach ($valid_seeds as $valid_seed) { diff --git a/classes/GUI/question_display/class.assStackQuestionDisplayGUI.php b/classes/GUI/question_display/class.assStackQuestionDisplayGUI.php index 6ba5ae10..9e3e7071 100644 --- a/classes/GUI/question_display/class.assStackQuestionDisplayGUI.php +++ b/classes/GUI/question_display/class.assStackQuestionDisplayGUI.php @@ -254,9 +254,9 @@ private function replacePlaceholders($show_feedback = FALSE) { $display = $this->getDisplay('prts', $prt_name); } - $question_text = str_replace("[[feedback:{$prt_name}]]", $display['display'], $this->getDisplay('question_text')); + $question_text = str_replace("[[feedback:{$prt_name}]]", assStackQuestionUtils::_replaceFeedbackPlaceHolders($display['display']), $this->getDisplay('question_text')); $this->setDisplay($question_text, 'question_text'); - $question_specific_feedback = str_replace("[[feedback:{$prt_name}]]", $display['display'], $this->getDisplay('question_specific_feedback')); + $question_specific_feedback = str_replace("[[feedback:{$prt_name}]]", assStackQuestionUtils::_replaceFeedbackPlaceHolders($display['display']), $this->getDisplay('question_specific_feedback')); $this->setDisplay($question_specific_feedback, 'question_specific_feedback'); } } else diff --git a/classes/GUI/question_display/class.assStackQuestionFeedbackGUI.php b/classes/GUI/question_display/class.assStackQuestionFeedbackGUI.php index b0763e7b..e6ccf243 100644 --- a/classes/GUI/question_display/class.assStackQuestionFeedbackGUI.php +++ b/classes/GUI/question_display/class.assStackQuestionFeedbackGUI.php @@ -51,9 +51,11 @@ function __construct(ilassStackQuestionPlugin $plugin, $feedback_data, $specific //Set feedback data $this->setFeedback($feedback_data); - if (sizeof($this->getFeedback('prt')) > 1) { + if (!empty($this->getFeedback('prt'))) + { $this->show_user_response = TRUE; - } else { + } else + { $this->show_user_response = FALSE; } @@ -62,7 +64,8 @@ function __construct(ilassStackQuestionPlugin $plugin, $feedback_data, $specific $mathJaxSetting = new ilSetting("MathJax"); $this->getTemplate()->addJavaScript($mathJaxSetting->get("path_to_mathjax")); - if (is_string($specific_feedback)) { + if (is_string($specific_feedback)) + { $this->specific_feedback = $specific_feedback; } } @@ -114,8 +117,10 @@ private function fillTemplate($graphical_output, $show_points, $show_feedback, $ //General feedback info $this->fillGeneralInfo($show_question_text, $show_points, $show_feedback, $show_correct_solution); //PRT Specific part - if (is_array($this->getFeedback('prt'))) { - foreach ($this->getFeedback('prt') as $prt_name => $prt) { + if (is_array($this->getFeedback('prt'))) + { + foreach ($this->getFeedback('prt') as $prt_name => $prt) + { $this->fillSpecificPrtFeedback($show_question_text, $prt_name, $prt, $graphical_output, $show_points, $show_feedback, $show_correct_solution); } } @@ -132,8 +137,10 @@ private function fillBestSolutionTemplate($mode = "correct") $this->getTemplate()->setVariable('QUESTION_TEXT', assStackQuestionUtils::_getLatex($this->getQuestionTextFilledIn($mode))); //Fill how to solve - if ($mode == "correct") { - $this->getTemplate()->setVariable('HOW_TO_SOLVE', assStackQuestionUtils::_getLatex($this->getQuestionHowToSolve($this->getFeedback('general_feedback')))); + if ($mode == "correct") + { + $text = assStackQuestionUtils::_getLatex($this->getQuestionHowToSolve($this->getFeedback('general_feedback'))); + $this->getTemplate()->setVariable('HOW_TO_SOLVE', assStackQuestionUtils::_getFeedbackStyledText($text, "feedback_solution_hint")); } @@ -175,18 +182,22 @@ private function fillBestSolutionTemplate($mode = "correct") private function fillGeneralInfo($show_question_text, $show_points, $show_feedback, $show_correct_solution) { // question_text - if ($this->getFeedback('question_text') != '' AND $_GET['activecommand'] != 'directfeedback') { + if ($this->getFeedback('question_text') != '' AND $_GET['activecommand'] != 'directfeedback') + { //If test is finished use LaTeX - if ($_GET['cmd'] != 'preview') { + if ($_GET['cmd'] != 'preview') + { $this->getTemplate()->setVariable('QUESTION_TEXT_MESSAGE', $this->getPlugin()->txt('message_question_text')); $this->getTemplate()->setVariable('QUESTION_TEXT', assStackQuestionUtils::_replacePlaceholders(assStackQuestionUtils::_getLatex($this->getFeedback('question_text')))); - } else { + } else + { $this->getTemplate()->setVariable('QUESTION_TEXT_MESSAGE', $this->getPlugin()->txt('message_question_text')); $this->getTemplate()->setVariable('QUESTION_TEXT', assStackQuestionUtils::_replacePlaceholders(assStackQuestionUtils::_getLatex($this->getFeedback('general_feedback')))); } - } elseif ($this->getFeedback('general_feedback') != '' AND $_GET['activecommand'] == 'directfeedback') { + } elseif ($this->getFeedback('general_feedback') != '' AND $_GET['activecommand'] == 'directfeedback') + { //If test is finished use LaTeX $this->getTemplate()->setVariable('QUESTION_TEXT_MESSAGE', $this->getPlugin()->txt('message_general_feedback')); @@ -194,11 +205,13 @@ private function fillGeneralInfo($show_question_text, $show_points, $show_feedba } //If there are general feedback to be shown - if ($show_feedback AND $this->getFeedback('general_feedback') != '') { + if ($show_feedback AND $this->getFeedback('general_feedback') != '') + { //If test is finished use LaTeX //$this->getTemplate()->setVariable('GENERAL_FEEDBACK_MESSAGE', $this->getPlugin()->txt('message_general_feedback')); //$this->getTemplate()->setVariable('GENERAL_FEEDBACK', assStackQuestionUtils::_getLatex($this->getFeedback('general_feedback'))); - } else { + } else + { //Show message for no general feedback. //v1.6.1 Not use general_feedback //$this->getTemplate()->setVariable('GENERAL_FEEDBACK', $this->getPlugin()->txt('message_no_how_to_solve_in_this_question')); @@ -233,27 +246,32 @@ private function fillSpecificPrtFeedback($show_question_text, $prt_name, $prt, $ $this->getTemplate()->setCurrentBlock('question_part'); $this->getTemplate()->setVariable('PRT_NAME', $prt_name); //Fill the user response part - if (($this->show_user_response AND $_GET['activecommand'] == 'directfeedback') OR $_GET['activecommand'] != 'directfeedback') { + if (($this->show_user_response AND $_GET['activecommand'] == 'directfeedback') OR $_GET['activecommand'] != 'directfeedback') + { $this->fillUserResponse($prt['response'], $show_correct_solution); } //Set block again to continue filling the question part $this->getTemplate()->setCurrentBlock('question_part'); //Points reached in this prt - if (($this->show_user_response AND $_GET['activecommand'] == 'directfeedback') OR $_GET['activecommand'] != 'directfeedback') { - if (!is_null($prt['points']) AND $show_points) { + if (($this->show_user_response AND $_GET['activecommand'] == 'directfeedback') OR $_GET['activecommand'] != 'directfeedback') + { + if (!is_null($prt['points']) AND $show_points) + { $this->getTemplate()->setVariable('POINTS_MESSAGE', $this->getPlugin()->txt('message_points')); $this->getTemplate()->setVariable('POINTS', $prt['points']); } } //Errors - if ($prt['errors'] AND $show_feedback) { + if ($prt['errors'] AND $show_feedback) + { $this->getTemplate()->setVariable('ERROR_MESSAGE', $this->getPlugin()->txt('message_error_part')); $this->getTemplate()->setVariable('ERROR', assStackQuestionUtils::_getLatex($prt['errors'])); } //Specific feedback given for this prt - if ($prt['feedback']) { + if ($prt['feedback']) + { //$this->getTemplate()->setVariable('FEEDBACK_MESSAGE', $this->getPlugin()->txt('message_feedback_solution_part')); $this->getTemplate()->setVariable('PART_FEEDBACK', assStackQuestionUtils::_getLatex($prt['feedback'])); } @@ -265,9 +283,11 @@ private function fillSpecificPrtFeedback($show_question_text, $prt_name, $prt, $ }*/ //Fill color for the feedback status of this input. - if ($graphical_output AND $_GET['cmd'] != 'outUserListOfAnswerPasses') { + if ($graphical_output AND $_GET['cmd'] != 'outUserListOfAnswerPasses') + { //Status message - if (is_array($prt['status'])) { + if (is_array($prt['status'])) + { $this->getTemplate()->setVariable('FEEDBACK_STATUS', $prt['status']['message']); } @@ -287,17 +307,20 @@ private function fillUserResponse($response_data, $show_correct_solution) { $this->getTemplate()->setVariable('USER_RESPONSE_CONTAINER_MESSAGE', $this->getPlugin()->txt('message_user_response_container')); //For each input evaluated in current PRT - foreach ($response_data as $input_name => $response) { + foreach ($response_data as $input_name => $response) + { //Set block $this->getTemplate()->setCurrentBlock('user_response_part'); //If there is a model answer to show - if (isset($response['model_answer'])) { + if (isset($response['model_answer'])) + { //User response $this->getTemplate()->setVariable('USER_RESPONSE_MESSAGE', $this->getPlugin()->txt('message_user_solution_part')); $this->getTemplate()->setVariable('USER_RESPONSE', $response['display']); //Teacher solution //TODO this may not work in all configurations detetmine how to call the system delimiters for LaTeX - if ($show_correct_solution AND $_GET['activecommand'] != 'directfeedback') { + if ($show_correct_solution AND $_GET['activecommand'] != 'directfeedback') + { //$this->getTemplate()->setVariable('TEACHER_ANSWER_MESSAGE', $this->getPlugin()->txt('message_best_solution')); //$this->getTemplate()->setVariable('TEACHER_ANSWER', ilUtil::insertLatexImages('\[ ' . assStackQuestionUtils::_solveKeyBracketsBug($response['model_answer'])) . ' \]'); } @@ -314,7 +337,8 @@ private function fillUserResponse($response_data, $show_correct_solution) */ private function getColor($status) { - switch ($status) { + switch ($status) + { case 1: return "#b5eeac"; case 0: @@ -331,21 +355,29 @@ public function getQuestionTextFilledIn($mode = "correct") $question_text = $this->getFeedback('question_text'); $specific_feedback = $this->specific_feedback; //$question_text = preg_replace('/\[\[validation:(.*?)\]\]/', "", $question_text); - if (is_array($this->getFeedback('prt'))) { - foreach ($this->getFeedback('prt') as $prt_name => $prt) { - if(is_array($prt['response'])){ - foreach ($prt['response'] as $input_name => $input) { - if ($input['model_answer'] != "" AND $mode == "correct") { + if (is_array($this->getFeedback('prt'))) + { + foreach ($this->getFeedback('prt') as $prt_name => $prt) + { + if (is_array($prt['response'])) + { + foreach ($prt['response'] as $input_name => $input) + { + if ($input['model_answer'] != "" AND $mode == "correct") + { $question_text = str_replace("[[input:" . $input_name . "]]", $input['model_answer'], $question_text); $question_text = str_replace("[[validation:" . $input_name . "]]", $input['model_answer_display'], $question_text); - } elseif ($input['model_answer'] != "" AND $mode == "user") { + } elseif ($input['model_answer'] != "" AND $mode == "user") + { $question_text = str_replace("[[input:" . $input_name . "]]", $this->getFilledInputUser($input['display']), $question_text); $question_text = str_replace("[[feedback:" . $prt_name . "]]", $this->replacementForPRTPlaceholders($prt, $prt_name, $input), $question_text); $specific_feedback = str_replace("[[feedback:" . $prt_name . "]]", $this->replacementForPRTPlaceholders($prt, $prt_name, $input), $specific_feedback); - } elseif ($mode == "user") { + } elseif ($mode == "user") + { $question_text = str_replace("[[input:" . $input_name . "]]", $this->getPlugin()->txt("no_model_solution_for_this_input"), $question_text); $question_text = str_replace("[[feedback:" . $prt_name . "]]", $this->replacementForPRTPlaceholders($prt, $prt_name, $input), $question_text); - } elseif ($mode == "correct") { + } elseif ($mode == "correct") + { $question_text = str_replace("[[input:" . $input_name . "]]", $this->getPlugin()->txt("no_model_solution_for_this_input"), $question_text); $question_text = str_replace("[[feedback:" . $prt_name . "]]", "", $question_text); } @@ -354,19 +386,18 @@ public function getQuestionTextFilledIn($mode = "correct") } } - if ($mode == "correct") { + if ($mode == "correct") + { $string = ""; //feedback - $string .= ''; - $deco_question_text = $string; - } elseif ($mode == "user") { + $deco_question_text = assStackQuestionUtils::_getFeedbackStyledText($string, "feedback_default"); + } elseif ($mode == "user") + { $deco_question_text = $question_text; } @@ -381,17 +412,21 @@ public function getQuestionTextFilledIn($mode = "correct") */ private function replacementForPRTPlaceholders($prt, $prt_name, $input) { + /* + * THIS FUNCTION WORKS ONLY FOR TEST, FOR PREVIEW GO TO PREVIWEGUI + */ $string = ""; //feedback - $string .= ''; - return $string; + + $config_options = assStackQuestionConfig::_getStoredSettings("feedback"); + + return assStackQuestionUtils::_getFeedbackStyledText($string, "feedback_default"); } private function getFilledInputUser($value) @@ -404,9 +439,9 @@ private function getQuestionHowToSolve($text) { $deco_how_to_solve = ""; - if ($text) { - $deco_how_to_solve = ''; + if ($text) + { + $deco_how_to_solve = assStackQuestionUtils::_getFeedbackStyledText($text,"feedback_default"); } return $deco_how_to_solve; @@ -464,17 +499,22 @@ private function setFeedback($feedback_data) */ public function getFeedback($selector = '', $prt_name = '') { - if ($selector AND $prt_name) { + if ($selector AND $prt_name) + { //For selection of specific data within an prt return $this->feedback['prt'][$prt_name][$selector]; - } elseif ($selector) { + } elseif ($selector) + { //For selection of specific data non related to an input. - if (isset($this->feedback[$selector])) { + if (isset($this->feedback[$selector])) + { return $this->feedback[$selector]; - } else { + } else + { return ""; } - } else { + } else + { return $this->feedback; } } @@ -482,11 +522,16 @@ public function getFeedback($selector = '', $prt_name = '') public function getUserAnswersFromFeedback() { $user_answers = array(); - if (is_array($this->getFeedback('prt'))) { - foreach ($this->getFeedback('prt') as $prt_name => $prt) { - if (isset($prt['response'])) { - foreach ($prt['response'] as $input_name => $value) { - if (!array_key_exists($input_name, $user_answers)) { + if (is_array($this->getFeedback('prt'))) + { + foreach ($this->getFeedback('prt') as $prt_name => $prt) + { + if (isset($prt['response'])) + { + foreach ($prt['response'] as $input_name => $value) + { + if (!array_key_exists($input_name, $user_answers)) + { $user_answers[$input_name] = $value['value']; } } diff --git a/classes/GUI/test/class.assStackQuestionTestGUI.php b/classes/GUI/test/class.assStackQuestionTestGUI.php index 010bd135..7605039f 100644 --- a/classes/GUI/test/class.assStackQuestionTestGUI.php +++ b/classes/GUI/test/class.assStackQuestionTestGUI.php @@ -100,7 +100,7 @@ public function showUnitTestsPanel($a_mode = FALSE) $toolbar->addButtonInstance($run_all_tests); $toolbar->setFormAction($ctrl->getLinkTargetByClass("assSTACKQuestionGUI")); - if (sizeof($this->getTests())) + if (!empty($this->getTests())) { include_once './Services/Accordion/classes/class.ilAccordionGUI.php'; $unit_tests_accordion = new ilAccordionGUI(); diff --git a/classes/class.assStackQuestion.php b/classes/class.assStackQuestion.php index c9055021..3bfab54e 100644 --- a/classes/class.assStackQuestion.php +++ b/classes/class.assStackQuestion.php @@ -879,7 +879,7 @@ public function saveAdditionalQuestionDataToDb($edit_question = "", $adding_to_t } //INPUTS - if (sizeof($this->inputs)) + if (!empty($this->inputs)) { foreach ($this->inputs as $input) { @@ -897,7 +897,7 @@ public function saveAdditionalQuestionDataToDb($edit_question = "", $adding_to_t } //POTENTIAL RESPONSE TREES - if (sizeof($this->potential_responses_trees)) + if (!empty($this->potential_responses_trees)) { foreach ($this->potential_responses_trees as $prt) { @@ -992,7 +992,7 @@ function beforeSyncWithOriginal($origQuestionId, $dupQuestionId, $origParentObjI } //Inputs - if (sizeof($this->inputs)) + if (!empty($this->inputs)) { $inputs = assStackQuestionInput::_read($origQuestionId); @@ -1025,7 +1025,7 @@ function beforeSyncWithOriginal($origQuestionId, $dupQuestionId, $origParentObjI } //PRT - if (sizeof($this->potential_responses_trees)) + if (!empty($this->potential_responses_trees)) { $prts = assStackQuestionPRT::_read($origQuestionId); @@ -1125,7 +1125,7 @@ function beforeCopy($origQuestionId) } //Inputs - if (sizeof($this->inputs)) + if (!empty($this->inputs)) { foreach ($this->inputs as $key => $input) { @@ -1138,7 +1138,7 @@ function beforeCopy($origQuestionId) } //PRT - if (sizeof($this->potential_responses_trees)) + if (!empty($this->potential_responses_trees)) { foreach ($this->potential_responses_trees as $prt_key => $prt) @@ -1240,7 +1240,7 @@ public function loadFromDb($question_id) //load inputs $this->getPlugin()->includeClass('model/ilias_object/class.assStackQuestionInput.php'); $this->setInputs(assStackQuestionInput::_read($question_id)); - if (sizeof($this->getInputs()) == 0) + if (empty($this->getInputs())) { //Create options $input = new assStackQuestionInput(-1, $question_id, "ans1", "algebraic", ""); @@ -1793,7 +1793,7 @@ public function getQuestionSeedForCurrentTestRun($active_id, $pass) } //Determine if seed already exists and return it; - if (sizeof($this->getPotentialResponsesTrees())) + if (!empty($this->getPotentialResponsesTrees())) { foreach ($this->getPotentialResponsesTrees() as $prt) { @@ -1819,7 +1819,7 @@ public function getQuestionSeedForCurrentTestRun($active_id, $pass) //get seed and save it to DB $question_seed = $this->getStackQuestion()->getSeed(); - if (sizeof($this->getPotentialResponsesTrees())) + if (!empty($this->getPotentialResponsesTrees())) { foreach ($this->getPotentialResponsesTrees() as $prt) { @@ -1943,5 +1943,12 @@ public function setErrors($error) $_SESSION["stack_authoring_errors"][$this->getId()][] = $error; } - + /** + * @param array $valuePairs + * @return array $indexedValues + */ + public function fetchIndexedValuesFromValuePairs(array $valuePairs) + { + return $valuePairs; + } } \ No newline at end of file diff --git a/classes/class.assStackQuestionGUI.php b/classes/class.assStackQuestionGUI.php index e826cb07..374a3d41 100644 --- a/classes/class.assStackQuestionGUI.php +++ b/classes/class.assStackQuestionGUI.php @@ -277,26 +277,33 @@ public function deletionManagement() public function checkPRTForDeletion(assStackQuestionPRT $prt) { - if (sizeof($this->object->getPotentialResponsesTrees()) < 2) + if (is_array($this->object->getPotentialResponsesTrees())) { - $this->object->setErrors($this->object->getPlugin()->txt('deletion_error_not_enought_prts')); + if (sizeof($this->object->getPotentialResponsesTrees()) < 2) + { + $this->object->setErrors($this->object->getPlugin()->txt('deletion_error_not_enought_prts')); - return TRUE; + return TRUE; + } } + return FALSE; } public function checkPRTNodeForDeletion(assStackQuestionPRT $prt, assStackQuestionPRTNode $node) { - - if (sizeof($prt->getPRTNodes()) < 2) + if (is_array($prt->getPRTNodes())) { - $this->object->setErrors($this->object->getPlugin()->txt('deletion_error_not_enought_prt_nodes')); + if (sizeof($prt->getPRTNodes()) < 2) + { + $this->object->setErrors($this->object->getPlugin()->txt('deletion_error_not_enought_prt_nodes')); - return TRUE; + return TRUE; + } } + if ((int)$prt->getFirstNodeName() == (int)$node->getNodeName()) { $this->object->setErrors($this->object->getPlugin()->txt('deletion_error_first_node')); @@ -343,11 +350,14 @@ public function writeQuestionSpecificPostData() } else { //If doesn' exist, check if must be deleted - if (sizeof($this->object->getInputs()) < 2) + if (is_array($this->object->getInputs())) { - //If there are less than two inputs you cannot delete it - //Add placeholder to question text - $this->object->setQuestion($this->object->getQuestion() . " [[input:{$input_name}]] [[validation:{$input_name}]]"); + if (sizeof($this->object->getInputs()) < 2) + { + //If there are less than two inputs you cannot delete it + //Add placeholder to question text + $this->object->setQuestion($this->object->getQuestion() . " [[input:{$input_name}]] [[validation:{$input_name}]]"); + } } else { //Delete input from object @@ -482,6 +492,14 @@ public function getPreview($show_question_only = FALSE, $showInlineFeedback = fa $tpl->addCss($this->plugin->getStyleSheetLocation('css/qpl_xqcas_question_preview.css')); $tpl->addCss($this->plugin->getStyleSheetLocation('css/qpl_xqcas_question_display.css')); + //Include content Style + $style_id = assStackQuestionUtils::_getActiveContentStyleId(); + if (strlen($style_id)) + { + require_once "./Services/Style/Content/classes/class.ilObjStyleSheet.php"; + $tpl->addCss(ilObjStyleSheet::getContentStylePath((int)$style_id)); + } + $questionoutput = $question_preview_gui->get(); //Returns output (with page if needed) if (!$show_question_only) @@ -504,6 +522,9 @@ public function getPreview($show_question_only = FALSE, $showInlineFeedback = fa */ public function getTestOutput($active_id, $pass = NULL, $is_question_postponed = FALSE, $user_post_solutions = FALSE, $show_specific_inline_feedback) { + $this->active_id = $active_id; + $this->pass = $pass; + $solutions = NULL; // get the solution of the user for the active pass or from the last pass if allowed if ($active_id) @@ -564,6 +585,15 @@ public function getTestQuestionOutput($solutions, $show_specific_inline_feedback $this->plugin->includeClass("GUI/question_display/class.assStackQuestionDisplayGUI.php"); //Get question display data $tpl->addCss($this->plugin->getStyleSheetLocation('css/qpl_xqcas_question_display.css')); + + //Include content Style + $style_id = assStackQuestionUtils::_getActiveContentStyleId(); + if (strlen($style_id)) + { + require_once "./Services/Style/Content/classes/class.ilObjStyleSheet.php"; + $tpl->addCss(ilObjStyleSheet::getContentStylePath((int)$style_id)); + } + $value_format_user_response = assStackQuestionUtils::_getUserResponse($this->object->getId(), $this->object->getStackQuestion()->getInputs(), $feedback_data); $question_display_object = new assStackQuestionDisplay($this->plugin, $this->object->getStackQuestion(), $value_format_user_response, $feedback_data); $question_display_data = $question_display_object->getQuestionDisplayData(TRUE); @@ -595,6 +625,8 @@ public function getTestQuestionOutput($solutions, $show_specific_inline_feedback function getSolutionOutput($active_id, $pass = NULL, $graphicalOutput = FALSE, $result_output = FALSE, $show_question_only = TRUE, $show_feedback = TRUE, $show_correct_solution = FALSE, $show_manual_scoring = FALSE, $show_question_text = TRUE) { $solution_template = new ilTemplate("tpl.il_as_tst_solution_output.html", TRUE, TRUE, "Modules/TestQuestionPool"); + $this->active_id = $active_id; + $this->pass = $pass; //Check for PASS if ($active_id) { @@ -631,7 +663,7 @@ function getSolutionOutput($active_id, $pass = NULL, $graphicalOutput = FALSE, $ //Returns user solution HTML $solution_output = $this->getQuestionOutput($solutions, FALSE, $show_feedback, TRUE); //2.3.12 add feedback to solution - $solution_output .= $this->getSpecificFeedbackOutput($active_id, $pass); + $solution_output .= $this->getSpecificFeedbackOutput($solutions); } else { @@ -699,6 +731,7 @@ public function getQuestionOutput($solutions, $best_solution, $show_feedback, $j { $question_text = $solutions["question_text"]; + //Get Model answer from solutions and replace placeholders if (isset($solutions["prt"])) { @@ -763,7 +796,7 @@ public function getQuestionOutput($solutions, $best_solution, $show_feedback, $j $question_text = str_replace("[[validation:" . $input_name . "]]", $validation_replacement, $question_text); } else { - $input_replacement = ""; + $input_replacement = ""; } $size = $input->getBoxSize(); $input_text = ""; @@ -794,7 +827,6 @@ public function getQuestionOutput($solutions, $best_solution, $show_feedback, $j } $size = strlen($input_replacement) + 5; $input_html_display = ''; - $question_text = str_replace("[[input:" . $input_name . "]]", $input_html_display, $question_text); break; } @@ -804,17 +836,12 @@ public function getQuestionOutput($solutions, $best_solution, $show_feedback, $j if ($show_feedback) { $string = ""; - //feedback - $string .= ''; - - $question_text = str_replace("[[feedback:" . $prt_name . "]]", $string, $question_text); + $question_text = str_replace("[[feedback:" . $prt_name . "]]", assStackQuestionUtils::_getFeedbackStyledText($string, "feedback_default"), $question_text); } } } @@ -843,14 +870,22 @@ public function getQuestionOutput($solutions, $best_solution, $show_feedback, $j } /** - * Return the specific feedback - * @param int $active_id - * @param int $pass - * @return string + * Returns the answer specific feedback for the question + * + * Please not that the solution array structure is STACK specific! + * + * @param array $userSolution ($userSolution[] = ) + * @return string HTML Code with the answer specific feedback + * @see assStackQuestion::getSolutionValues() **/ - public function getSpecificFeedbackOutput($active_id, $pass) + public function getSpecificFeedbackOutput($userSolution) { - //Check for PASS + //We cannot use $userSolution, we need to get active id and pass to get the +//Check for PASS + + $active_id = $this->active_id; + $pass = $this->pass; + if ($active_id) { require_once './Modules/Test/classes/class.ilObjTest.php'; @@ -878,6 +913,7 @@ public function getSpecificFeedbackOutput($active_id, $pass) } } $specific_feedback = $this->object->getOptions()->getSpecificFeedback(); + //Search for feedback placeholders in specific feedback text. foreach ($this->object->getPotentialResponsesTrees() as $prt_name => $prt) { @@ -887,15 +923,13 @@ public function getSpecificFeedbackOutput($active_id, $pass) { $string = ""; //feedback - $string .= ''; - $specific_feedback = str_replace("[[feedback:" . $prt_name . "]]", $string, $specific_feedback); + + $specific_feedback = str_replace("[[feedback:" . $prt_name . "]]", assStackQuestionUtils::_getFeedbackStyledText($string, "feedback_default"), $specific_feedback); } else { $specific_feedback = str_replace("[[feedback:" . $prt_name . "]]", $this->object->getPlugin()->txt("preview_no_answer"), $specific_feedback); @@ -910,11 +944,11 @@ public function getSpecificFeedbackOutput($active_id, $pass) /** * Returns the answer generic feedback depending on the results of the question * - * @deprecated Use getGenericFeedbackOutput instead. * @param integer $active_id Active ID of the user * @param integer $pass Active pass * @return string HTML Code with the answer specific feedback * @access public + * @deprecated Use getGenericFeedbackOutput instead. */ function getAnswerFeedbackOutput($active_id, $pass) { @@ -1610,6 +1644,14 @@ public function importQuestionFromMoodleForm() $lng = $DIC->language(); $tabs = $DIC->tabs(); + + //#25145 + if (isset($_REQUEST["test_ref_id"])) + { + ilUtil::sendFailure($lng->txt("qpl_qst_xqcas_import_in_test_error"), TRUE); + $DIC->ctrl()->redirect($this, 'editQuestion'); + } + if ($this->object->getSelfAssessmentEditingMode()) { $this->getLearningModuleTabs(); diff --git a/classes/class.ilassStackQuestionConfigGUI.php b/classes/class.ilassStackQuestionConfigGUI.php index 98237ee1..383bdb13 100644 --- a/classes/class.ilassStackQuestionConfigGUI.php +++ b/classes/class.ilassStackQuestionConfigGUI.php @@ -16,12 +16,12 @@ */ class ilassStackQuestionConfigGUI extends ilPluginConfigGUI { - /** @var assStackQuestionConfig */ - protected $config; + /** @var assStackQuestionConfig */ + protected $config; - /** @var ilassStackQuestionPlugin */ - protected $plugin_object = null; + /** @var ilassStackQuestionPlugin */ + protected $plugin_object = null; /** * @@ -40,17 +40,17 @@ public function performCommand($cmd) $cmd = $ctrl->getCmd($this, "configure"); switch ($cmd) { - case 'configure'; - case 'showConnectionSettings': - case 'saveConnectionSettings': - case 'showServerList': - case 'addServer': - case 'editServer': - case 'saveConnectionSettings': - case 'saveServerSettings': - case 'confirmDeleteServers': - $this->initTabs('show_connection_settings'); - break; + case 'configure'; + case 'showConnectionSettings': + case 'saveConnectionSettings': + case 'showServerList': + case 'addServer': + case 'editServer': + case 'saveConnectionSettings': + case 'saveServerSettings': + case 'confirmDeleteServers': + $this->initTabs('show_connection_settings'); + break; case 'showOtherSettings': case 'showDisplaySettings': @@ -65,21 +65,24 @@ public function performCommand($cmd) case 'setDefaultSettingsForInputs': case 'setDefaultSettingsForOptions': case 'setDefaultSettingsForPRTs': + case 'showFeedbackStylesSettings': + case 'saveFeedbackStylesSettings': + case 'setFeedbackStylesSettings': $this->initTabs('show_other_settings'); break; case 'showHealthcheck': - case 'runHealthcheck': + case 'runHealthcheck': $this->initTabs('show_healthcheck'); break; } - $this->$cmd(); + $this->$cmd(); } /** - * Init the tabs - * @param string $a_active id of the active tab (activates it an adds its sub tabs) + * Init the tabs + * @param string $a_active id of the active tab (activates it an adds its sub tabs) */ public function initTabs($a_active = "") { @@ -87,27 +90,28 @@ public function initTabs($a_active = "") $ctrl = $DIC->ctrl(); $tabs = $DIC->tabs(); - $tabs->addTab("show_connection_settings", $this->plugin_object->txt('show_connection_settings'), $ctrl->getLinkTarget($this, 'showConnectionSettings')); - $tabs->addTab("show_other_settings", $this->plugin_object->txt('show_other_settings'), $ctrl->getLinkTarget($this, 'showOtherSettings')); - $tabs->addTab("show_healthcheck", $this->plugin_object->txt('show_healthcheck'), $ctrl->getLinkTarget($this, 'showHealthcheck')); + $tabs->addTab("show_connection_settings", $this->plugin_object->txt('show_connection_settings'), $ctrl->getLinkTarget($this, 'showConnectionSettings')); + $tabs->addTab("show_other_settings", $this->plugin_object->txt('show_other_settings'), $ctrl->getLinkTarget($this, 'showOtherSettings')); + $tabs->addTab("show_healthcheck", $this->plugin_object->txt('show_healthcheck'), $ctrl->getLinkTarget($this, 'showHealthcheck')); - $tabs->activateTab($a_active); + $tabs->activateTab($a_active); - switch ($a_active) + switch ($a_active) { - case 'show_connection_settings': - $tabs->addSubTab('basic_connection_settings', $this->plugin_object->txt('basic_connection_settings'), $ctrl->getLinkTarget($this, 'showConnectionSettings')); - if ($this->config->get('platform_type') == 'server') - { - $tabs->addSubTab('server_configuration', $this->plugin_object->txt('server_configuration'), $ctrl->getLinkTarget($this, 'showServerList')); - } - break; + case 'show_connection_settings': + $tabs->addSubTab('basic_connection_settings', $this->plugin_object->txt('basic_connection_settings'), $ctrl->getLinkTarget($this, 'showConnectionSettings')); + if ($this->config->get('platform_type') == 'server') + { + $tabs->addSubTab('server_configuration', $this->plugin_object->txt('server_configuration'), $ctrl->getLinkTarget($this, 'showServerList')); + } + break; case 'show_other_settings': $tabs->addSubTab('show_display_settings', $this->plugin_object->txt('show_display_settings'), $ctrl->getLinkTargetByClass('ilassStackQuestionConfigGUI', 'showDisplaySettings')); $tabs->addSubTab('show_default_options_settings', $this->plugin_object->txt('show_default_options_settings'), $ctrl->getLinkTargetByClass('ilassStackQuestionConfigGUI', 'showDefaultOptionsSettings')); $tabs->addSubTab('show_default_inputs_settings', $this->plugin_object->txt('show_default_inputs_settings'), $ctrl->getLinkTargetByClass('ilassStackQuestionConfigGUI', 'showDefaultInputsSettings')); $tabs->addSubTab('show_default_prts_settings', $this->plugin_object->txt('show_default_prts_settings'), $ctrl->getLinkTargetByClass('ilassStackQuestionConfigGUI', 'showDefaultPRTsSettings')); + $tabs->addSubTab('show_feedback_styles_settings', $this->plugin_object->txt('feedback_styles_settings'), $ctrl->getLinkTargetByClass('ilassStackQuestionConfigGUI', 'showFeedbackStylesSettings')); break; } } @@ -127,155 +131,151 @@ function configure() public function showConnectionSettings() { - global $DIC, $tpl; - $tabs = $DIC->tabs(); - $tabs->activateSubTab('basic_connection_settings'); + global $DIC, $tpl; + $tabs = $DIC->tabs(); + $tabs->activateSubTab('basic_connection_settings'); $form = $this->getConnectionSettingsForm(); $tpl->setContent($form->getHTML()); } public function showServerList() - { - global $DIC, $tpl; - $DIC->tabs()->activateSubTab('server_configuration'); - - $button = ilLinkButton::getInstance(); - $button->setCaption($this->plugin_object->txt('add_server'), false); - $button->setUrl($DIC->ctrl()->getLinkTarget($this, 'addServer')); - $DIC->toolbar()->addButtonInstance($button); - - $this->plugin_object->includeClass('GUI/tables/class.assStackQuestionServerTableGUI.php'); - $table = new assStackQuestionServerTableGUI($this, 'showServerList'); - $tpl->setContent($table->getHTML()); - } - - public function addServer() - { - global $DIC, $tpl; - $tabs = $DIC->tabs(); - $tabs->activateSubTab('server_configuration'); - - $form = $this->getServerSettingsForm(); - $tpl->setContent($form->getHTML()); - } - - public function editServer() - { - global $DIC, $tpl; - $tabs = $DIC->tabs(); - $tabs->activateSubTab('server_configuration'); - - $DIC->ctrl()->setParameter($this, 'server_id', $_GET['server_id']); - $button = ilLinkButton::getInstance(); - $button->setCaption($this->plugin_object->txt('show_healthcheck'), false); - $button->setUrl($DIC->ctrl()->getLinkTarget($this, 'runHealthcheck')); - $DIC->toolbar()->addButtonInstance($button); - - $form = $this->getServerSettingsForm($_GET['server_id']); - $tpl->setContent($form->getHTML()); - } - - - public function activateServers() - { - $this->changeServerActivation(true); - } - - public function deactivateServers() - { - $this->changeServerActivation(false); - } - - protected function changeServerActivation($active) - { - global $DIC; - - $this->plugin_object->includeClass("model/configuration/class.assStackQuestionServer.php"); - - if (isset($_POST['server_id'])) - { - $server_ids = (array) $_POST['server_id']; - } - elseif (isset($_GET['server_id'])) - { - $server_ids = (array) $_GET['server_id']; - } - - if (empty($server_ids)) - { - ilUtil::sendFailure($this->plugin_object->txt('no_server_selected'), true); - } - else - { - foreach ($server_ids as $server_id) - { - $server = assStackQuestionServer::getServerById($server_id); - $server->setActive($active); - } - assStackQuestionServer::saveServers(); - - if (count($server_ids) == 1) - { - ilUtil::sendSuccess($this->plugin_object->txt($active ? 'server_activated' : 'server_deactivated'), true); - } - else - { - ilUtil::sendSuccess($this->plugin_object->txt($active ? 'servers_activated' : 'servers_deactivated'), true); - } - } - $DIC->ctrl()->redirect($this, 'showServerList'); - } - - public function confirmDeleteServers() - { - global $DIC, $tpl; - - $this->plugin_object->includeClass("model/configuration/class.assStackQuestionServer.php"); - - if (isset($_POST['server_id'])) - { - $server_ids = (array) $_POST['server_id']; - } - elseif (isset($_GET['server_id'])) - { - $server_ids = (array) $_GET['server_id']; - } - - if (empty($server_ids)) - { - ilUtil::sendFailure($this->plugin_object->txt('no_server_selected'), true); - $DIC->ctrl()->redirect($this, 'showServerList'); - } - - $gui = new ilConfirmationGUI(); - $gui->setHeaderText($this->plugin_object->txt('confirm_delete_servers')); - $gui->setFormAction($DIC->ctrl()->getFormAction($this)); - $gui->setConfirm($DIC->language()->txt('delete'), 'deleteServers'); - $gui->setCancel($DIC->language()->txt('cancel'), 'showServerList'); - - foreach ($server_ids as $server_id) - { - $server = assStackQuestionServer::getServerById($server_id); - $gui->addItem('server_id[]', $server_id, $server->getAddress()); - } - $tpl->setContent($gui->getHTML()); - } - - public function deleteServers() - { - global $DIC; - $this->plugin_object->includeClass("model/configuration/class.assStackQuestionServer.php"); - - $server_ids = (array) $_POST['server_id']; - assStackQuestionServer::deleteServers($server_ids); - - ilUtil::sendSuccess($this->plugin_object->txt(count($server_ids) == 1 ? 'server_deleted' : 'servers_deleted'), true); - $DIC->ctrl()->redirect($this, 'showServerList'); - } - - - public function showOtherSettings() + { + global $DIC, $tpl; + $DIC->tabs()->activateSubTab('server_configuration'); + + $button = ilLinkButton::getInstance(); + $button->setCaption($this->plugin_object->txt('add_server'), false); + $button->setUrl($DIC->ctrl()->getLinkTarget($this, 'addServer')); + $DIC->toolbar()->addButtonInstance($button); + + $this->plugin_object->includeClass('GUI/tables/class.assStackQuestionServerTableGUI.php'); + $table = new assStackQuestionServerTableGUI($this, 'showServerList'); + $tpl->setContent($table->getHTML()); + } + + public function addServer() + { + global $DIC, $tpl; + $tabs = $DIC->tabs(); + $tabs->activateSubTab('server_configuration'); + + $form = $this->getServerSettingsForm(); + $tpl->setContent($form->getHTML()); + } + + public function editServer() + { + global $DIC, $tpl; + $tabs = $DIC->tabs(); + $tabs->activateSubTab('server_configuration'); + + $DIC->ctrl()->setParameter($this, 'server_id', $_GET['server_id']); + $button = ilLinkButton::getInstance(); + $button->setCaption($this->plugin_object->txt('show_healthcheck'), false); + $button->setUrl($DIC->ctrl()->getLinkTarget($this, 'runHealthcheck')); + $DIC->toolbar()->addButtonInstance($button); + + $form = $this->getServerSettingsForm($_GET['server_id']); + $tpl->setContent($form->getHTML()); + } + + + public function activateServers() + { + $this->changeServerActivation(true); + } + + public function deactivateServers() + { + $this->changeServerActivation(false); + } + + protected function changeServerActivation($active) + { + global $DIC; + + $this->plugin_object->includeClass("model/configuration/class.assStackQuestionServer.php"); + + if (isset($_POST['server_id'])) + { + $server_ids = (array)$_POST['server_id']; + } elseif (isset($_GET['server_id'])) + { + $server_ids = (array)$_GET['server_id']; + } + + if (empty($server_ids)) + { + ilUtil::sendFailure($this->plugin_object->txt('no_server_selected'), true); + } else + { + foreach ($server_ids as $server_id) + { + $server = assStackQuestionServer::getServerById($server_id); + $server->setActive($active); + } + assStackQuestionServer::saveServers(); + + if (count($server_ids) == 1) + { + ilUtil::sendSuccess($this->plugin_object->txt($active ? 'server_activated' : 'server_deactivated'), true); + } else + { + ilUtil::sendSuccess($this->plugin_object->txt($active ? 'servers_activated' : 'servers_deactivated'), true); + } + } + $DIC->ctrl()->redirect($this, 'showServerList'); + } + + public function confirmDeleteServers() + { + global $DIC, $tpl; + + $this->plugin_object->includeClass("model/configuration/class.assStackQuestionServer.php"); + + if (isset($_POST['server_id'])) + { + $server_ids = (array)$_POST['server_id']; + } elseif (isset($_GET['server_id'])) + { + $server_ids = (array)$_GET['server_id']; + } + + if (empty($server_ids)) + { + ilUtil::sendFailure($this->plugin_object->txt('no_server_selected'), true); + $DIC->ctrl()->redirect($this, 'showServerList'); + } + + $gui = new ilConfirmationGUI(); + $gui->setHeaderText($this->plugin_object->txt('confirm_delete_servers')); + $gui->setFormAction($DIC->ctrl()->getFormAction($this)); + $gui->setConfirm($DIC->language()->txt('delete'), 'deleteServers'); + $gui->setCancel($DIC->language()->txt('cancel'), 'showServerList'); + + foreach ($server_ids as $server_id) + { + $server = assStackQuestionServer::getServerById($server_id); + $gui->addItem('server_id[]', $server_id, $server->getAddress()); + } + $tpl->setContent($gui->getHTML()); + } + + public function deleteServers() + { + global $DIC; + $this->plugin_object->includeClass("model/configuration/class.assStackQuestionServer.php"); + + $server_ids = (array)$_POST['server_id']; + assStackQuestionServer::deleteServers($server_ids); + + ilUtil::sendSuccess($this->plugin_object->txt(count($server_ids) == 1 ? 'server_deleted' : 'servers_deleted'), true); + $DIC->ctrl()->redirect($this, 'showServerList'); + } + + + public function showOtherSettings() { global $DIC; $tabs = $DIC->tabs(); @@ -324,10 +324,21 @@ public function showDefaultPRTsSettings() $tpl->setContent($form->getHTML()); } + public function showFeedbackStylesSettings() + { + global $DIC, $tpl; + $tabs = $DIC->tabs(); + $tabs->setTabActive('show_other_settings'); + $tabs->setSubTabActive('show_feedback_styles_settings'); + + $form = $this->getFeedbackStylesSettingsForm(); + $tpl->setContent($form->getHTML()); + } + /** * Show the healthcheck screen - * @param bool $a_run run the healthcheck + * @param bool $a_run run the healthcheck */ public function showHealthcheck($a_run = false) { @@ -351,10 +362,10 @@ public function showHealthcheck($a_run = false) if ($a_run) { - if ($this->config->get('platform_type') == 'server') - { - ilUtil::sendInfo($this->plugin_object->txt('srv_address') . ':
'. assStackQuestionConfig::_getServerAddress()); - } + if ($this->config->get('platform_type') == 'server') + { + ilUtil::sendInfo($this->plugin_object->txt('srv_address') . ':
' . assStackQuestionConfig::_getServerAddress()); + } //Create Healthcheck $this->plugin_object->includeClass("model/configuration/class.assStackQuestionHealthcheck.php"); @@ -382,13 +393,13 @@ public function showHealthcheck($a_run = false) $tpl->setContent($toolbar->getHTML() . $result_html); } - /** - * Run a healthcheck - */ - public function runHealthcheck() - { - $this->showHealthcheck(true); - } + /** + * Run a healthcheck + */ + public function runHealthcheck() + { + $this->showHealthcheck(true); + } /* * FORMS CREATION METHODS @@ -453,26 +464,26 @@ public function getConnectionSettingsForm() $cas_result_caching->setValue('db'); $form->addItem($cas_result_caching); - if ($connection_data['platform_type'] == 'win') { - - //Maxima command - $maxima_command = new ilTextInputGUI($this->plugin_object->txt('maxima_command'), 'maxima_command'); - $maxima_command->setInfo($this->plugin_object->txt('maxima_command_info')); - $maxima_command->setValue($connection_data['maxima_command']); - $form->addItem($maxima_command); - } - elseif ($connection_data['platform_type'] == 'server') - { - $link = $DIC->ctrl()->getLinkTarget($this,'showServerList'); - $maxima_command = new ilNonEditableValueGUI($this->plugin_object->txt('maxima_command'), ''); - $maxima_command->setValue($this->plugin_object->txt('maxima_command_server')); - $maxima_command->setInfo(sprintf($this->plugin_object->txt('maxima_command_server_info'), $link)); - $form->addItem($maxima_command); - } - - if ($connection_data['platform_type'] == 'win' OR $connection_data['platform_type'] == 'server') - { - //Plot command + if ($connection_data['platform_type'] == 'win') + { + + //Maxima command + $maxima_command = new ilTextInputGUI($this->plugin_object->txt('maxima_command'), 'maxima_command'); + $maxima_command->setInfo($this->plugin_object->txt('maxima_command_info')); + $maxima_command->setValue($connection_data['maxima_command']); + $form->addItem($maxima_command); + } elseif ($connection_data['platform_type'] == 'server') + { + $link = $DIC->ctrl()->getLinkTarget($this, 'showServerList'); + $maxima_command = new ilNonEditableValueGUI($this->plugin_object->txt('maxima_command'), ''); + $maxima_command->setValue($this->plugin_object->txt('maxima_command_server')); + $maxima_command->setInfo(sprintf($this->plugin_object->txt('maxima_command_server_info'), $link)); + $form->addItem($maxima_command); + } + + if ($connection_data['platform_type'] == 'win' OR $connection_data['platform_type'] == 'server') + { + //Plot command $plot_command = new ilTextInputGUI($this->plugin_object->txt('plot_command'), 'plot_command'); $plot_command->setInfo($this->plugin_object->txt('plot_command_info')); $plot_command->setValue($connection_data['plot_command']); @@ -846,59 +857,168 @@ public function getDefaultPRTSettingsForm() } public function getServerSettingsForm($a_server_id = null) - { - global $DIC; - $ctrl = $DIC->ctrl(); - $lng = $DIC->language(); - - $this->plugin_object->includeClass("model/configuration/class.assStackQuestionServer.php"); - - if (isset($a_server_id) && $a_server_id > 0) - { - $server = assStackQuestionServer::getServerById($a_server_id); - $title = $this->plugin_object->txt('edit_server'); - $ctrl->setParameter($this, 'server_id', $a_server_id); - } - else - { - $server = assStackQuestionServer::getDefaultServer(); - $title = $this->plugin_object->txt('add_server'); - } - - $form = new ilPropertyFormGUI(); - $form->setTitle($title); - $form->setFormAction($ctrl->getFormAction($this)); - - // purpose - $options = []; - foreach (assStackQuestionServer::getPurposes() as $purpose) - { - $options[$purpose] = $this->plugin_object->txt('srv_purpose_' . $purpose); - } - $purpose = new ilSelectInputGUI($this->plugin_object->txt('srv_purpose'), 'purpose'); - $purpose->setInfo($this->plugin_object->txt('srv_purpose_info')); - $purpose->setRequired(true); - $purpose->setOptions($options); - $purpose->setValue($server->getPurpose()); - $form->addItem($purpose); - - $address = new ilTextInputGUI($this->plugin_object->txt('srv_address'), 'address'); - $address->setInfo($this->plugin_object->txt('srv_address_info')); - $address->setRequired(true); - $address->setValue($server->getAddress()); - $form->addItem($address); - - $active = new ilCheckboxInputGUI($lng->txt('active'), 'active'); - $active->setInfo($this->plugin_object->txt('srv_active_info')); - $active->setChecked($server->isActive()); - $form->addItem($active); - - $form->addCommandButton('saveServerSettings', $lng->txt('save')); - $form->addCommandButton('showServerList', $lng->txt('cancel')); - - return $form; - } + { + global $DIC; + $ctrl = $DIC->ctrl(); + $lng = $DIC->language(); + + $this->plugin_object->includeClass("model/configuration/class.assStackQuestionServer.php"); + + if (isset($a_server_id) && $a_server_id > 0) + { + $server = assStackQuestionServer::getServerById($a_server_id); + $title = $this->plugin_object->txt('edit_server'); + $ctrl->setParameter($this, 'server_id', $a_server_id); + } else + { + $server = assStackQuestionServer::getDefaultServer(); + $title = $this->plugin_object->txt('add_server'); + } + + $form = new ilPropertyFormGUI(); + $form->setTitle($title); + $form->setFormAction($ctrl->getFormAction($this)); + + // purpose + $options = []; + foreach (assStackQuestionServer::getPurposes() as $purpose) + { + $options[$purpose] = $this->plugin_object->txt('srv_purpose_' . $purpose); + } + $purpose = new ilSelectInputGUI($this->plugin_object->txt('srv_purpose'), 'purpose'); + $purpose->setInfo($this->plugin_object->txt('srv_purpose_info')); + $purpose->setRequired(true); + $purpose->setOptions($options); + $purpose->setValue($server->getPurpose()); + $form->addItem($purpose); + + $address = new ilTextInputGUI($this->plugin_object->txt('srv_address'), 'address'); + $address->setInfo($this->plugin_object->txt('srv_address_info')); + $address->setRequired(true); + $address->setValue($server->getAddress()); + $form->addItem($address); + + $active = new ilCheckboxInputGUI($lng->txt('active'), 'active'); + $active->setInfo($this->plugin_object->txt('srv_active_info')); + $active->setChecked($server->isActive()); + $form->addItem($active); + + $form->addCommandButton('saveServerSettings', $lng->txt('save')); + $form->addCommandButton('showServerList', $lng->txt('cancel')); + + return $form; + } + + public function getFeedbackStylesSettingsForm() + { + global $DIC; + $ctrl = $DIC->ctrl(); + $db = $DIC->database(); + $lng = $DIC->language(); + + require_once("./Services/Form/classes/class.ilPropertyFormGUI.php"); + $form = new ilPropertyFormGUI(); + $form->setFormAction($ctrl->getFormAction($this)); + + //Values from DB + $feedback_data = assStackQuestionConfig::_getStoredSettings('feedback'); + + //Get all Styles available + $styles_array = array(); + $styles_array["0"] = $lng->txt("default"); + + $stylesheet_active = $feedback_data["feedback_stylesheet_id"]; + + //Available standard styles + require_once "./Services/Style/Content/classes/class.ilObjStyleSheet.php"; + $available_styles = ilObjStyleSheet::_getStandardStyles(); + $available_styles[""] = $lng->txt("default"); + + //Feedback Stylesheet selection + $header = new ilFormSectionHeaderGUI(); + $header->setTitle($this->plugin_object->txt("feedback_stylesheet_id")); + $form->addItem($header); + + $feedback_stylesheet_id = new ilSelectInputGUI($this->plugin_object->txt('feedback_stylesheet_id'), 'feedback_stylesheet_id'); + $feedback_stylesheet_id->setOptions($available_styles); + $feedback_stylesheet_id->setInfo($this->plugin_object->txt('feedback_stylesheet_id_info')); + $feedback_stylesheet_id->setValue($feedback_data['feedback_stylesheet_id']); + $form->addItem($feedback_stylesheet_id); + if (strlen($stylesheet_active)) + { + $query = "SELECT style_id, characteristic FROM style_char WHERE type = 'text_block' AND style_id = '" . $stylesheet_active . "' "; + $result = $db->query($query); + while ($row = $db->fetchAssoc($result)) + { + $styles_array[$row["characteristic"]] = $row["characteristic"]; + } + } + + /* + * AS WE ARE USING THE TRUE/FALSE FEEDBACK FORMAT FIELD OF THE DATABASE + * WHICH IS NOT USED AT THE MOMENT, AND IS ALWAYS 0 OR 1. WE HAVE TO + * DEFINE VALUES FOR EACH OF THE FEEDBACK STYLES, BEGINNING BY 2, TO DISTINGUISH + * QUESTION WHICH USES THIS STYLES AND THOSE WHICH NOT. + */ + + //General Feedback Style + $header = new ilFormSectionHeaderGUI(); + $header->setTitle($this->plugin_object->txt("feedback_default")); + $form->addItem($header); + + //Feedback DEFAULT style ---> 1 + $feedback_default = new ilSelectInputGUI($this->plugin_object->txt('feedback_default'), 'feedback_default'); + $feedback_default->setOptions($styles_array); + $feedback_default->setInfo($this->plugin_object->txt('feedback_default_info')); + $feedback_default->setValue($feedback_data['feedback_default']); + $form->addItem($feedback_default); + + //Nodes feedback + $header = new ilFormSectionHeaderGUI(); + $header->setTitle($this->plugin_object->txt("nodes_feedback")); + $form->addItem($header); + + //Feedback style for right responses ---> 2 + $right_responses = new ilSelectInputGUI($this->plugin_object->txt('feedback_node_right'), 'feedback_node_right'); + $right_responses->setOptions($styles_array); + $right_responses->setInfo($this->plugin_object->txt('feedback_node_right_info')); + $right_responses->setValue($feedback_data['feedback_node_right']); + $form->addItem($right_responses); + + //Feedback style for wrong responses ---> 3 + $wrong_responses = new ilSelectInputGUI($this->plugin_object->txt('feedback_node_wrong'), 'feedback_node_wrong'); + $wrong_responses->setOptions($styles_array); + $wrong_responses->setInfo($this->plugin_object->txt('feedback_node_wrong_info')); + $wrong_responses->setValue($feedback_data['feedback_node_wrong']); + $form->addItem($wrong_responses); + + //Feedback style for solution hint ---> 4 + $solution_hint = new ilSelectInputGUI($this->plugin_object->txt('feedback_solution_hint'), 'feedback_solution_hint'); + $solution_hint->setOptions($styles_array); + $solution_hint->setInfo($this->plugin_object->txt('feedback_solution_hint_info')); + $solution_hint->setValue($feedback_data['feedback_solution_hint']); + $form->addItem($solution_hint); + + //Feedback style for Extra Information ---> 5 + $extra_info = new ilSelectInputGUI($this->plugin_object->txt('feedback_extra_info'), 'feedback_extra_info'); + $extra_info->setOptions($styles_array); + $extra_info->setInfo($this->plugin_object->txt('feedback_extra_info_info')); + $extra_info->setValue($feedback_data['feedback_extra_info']); + $form->addItem($extra_info); + + //Feedback style for Plot ---> 6 + $plot_feedback = new ilSelectInputGUI($this->plugin_object->txt('feedback_plot_feedback'), 'feedback_plot_feedback'); + $plot_feedback->setOptions($styles_array); + $plot_feedback->setInfo($this->plugin_object->txt('feedback_plot_feedback_info')); + $plot_feedback->setValue($feedback_data['feedback_plot_feedback']); + $form->addItem($plot_feedback); + + $form->addCommandButton("saveFeedbackStylesSettings", $this->plugin_object->txt("save")); + $form->addCommandButton("showFeedbackStylesSettings", $this->plugin_object->txt("cancel")); + + return $form; + } public function clearCache() { @@ -992,33 +1112,44 @@ public function saveDefaultPRTsSettings() } public function saveServerSettings() - { - global $DIC, $tpl; - $form = $this->getServerSettingsForm($_GET['server_id']); - if ($form->checkInput()) - { - if (isset($_GET['server_id'])) - { - $server = assStackQuestionServer::getServerById($_GET['server_id']); - } - else - { - $server = assStackQuestionServer::getDefaultServer(); - } - $server->setPurpose($form->getInput('purpose')); - $server->setAddress($form->getInput('address')); - $server->setActive($form->getInput('active')); - $server->save(); - - ilUtil::sendSuccess($this->plugin_object->txt('server_saved'), true); - $DIC->ctrl()->redirect($this, 'showServerList'); - } - else - { - $form->setValuesByPost(); - $tpl->setContent($form->getHTML()); - } - } + { + global $DIC, $tpl; + $form = $this->getServerSettingsForm($_GET['server_id']); + if ($form->checkInput()) + { + if (isset($_GET['server_id'])) + { + $server = assStackQuestionServer::getServerById($_GET['server_id']); + } else + { + $server = assStackQuestionServer::getDefaultServer(); + } + $server->setPurpose($form->getInput('purpose')); + $server->setAddress($form->getInput('address')); + $server->setActive($form->getInput('active')); + $server->save(); + + ilUtil::sendSuccess($this->plugin_object->txt('server_saved'), true); + $DIC->ctrl()->redirect($this, 'showServerList'); + } else + { + $form->setValuesByPost(); + $tpl->setContent($form->getHTML()); + } + } + + public function saveFeedbackStylesSettings() + { + $ok = $this->config->saveFeedbackStyleSettings(); + if ($ok) + { + ilUtil::sendSuccess($this->plugin_object->txt('config_feedback_styles_changed_message')); + } else + { + ilUtil::sendFailure($this->plugin_object->txt('config_error_message')); + } + $this->showFeedbackStylesSettings(); + } /* diff --git a/classes/export/MoodleXML/class.assStackQuestionMoodleXMLExport.php b/classes/export/MoodleXML/class.assStackQuestionMoodleXMLExport.php index 21d80b7d..c66bf9db 100644 --- a/classes/export/MoodleXML/class.assStackQuestionMoodleXMLExport.php +++ b/classes/export/MoodleXML/class.assStackQuestionMoodleXMLExport.php @@ -25,9 +25,11 @@ function __construct($stack_questions) global $DIC; $lng = $DIC->language(); - if (is_array($stack_questions) AND sizeof($stack_questions)) { + if (is_array($stack_questions) AND sizeof($stack_questions)) + { $this->setStackQuestions($stack_questions); - } else { + } else + { throw new stack_exception($lng->txt('qpl_qst_xqcas_moodlexml_no_questions_selected')); } } @@ -61,7 +63,8 @@ function toMoodleXML() // set xml header $a_xml_writer->xmlHeader(); $a_xml_writer->xmlStartTag("quiz"); - foreach ($this->getStackQuestions() as $question_id => $question) { + foreach ($this->getStackQuestions() as $question_id => $question) + { $a_xml_writer->xmlComment(" question: " . $question_id . " "); $a_xml_writer->xmlStartTag("question", array("type" => "stack")); @@ -88,15 +91,19 @@ function toMoodleXML() //Grade and penalty $a_xml_writer->xmlElement("defaultgrade", NULL, $question->getPoints()); - if ($question->getExtraInfo()->getPenalty()) { + if ($question->getExtraInfo()->getPenalty()) + { $a_xml_writer->xmlElement("penalty", NULL, $question->getExtraInfo()->getPenalty()); - } else { + } else + { $a_xml_writer->xmlElement("penalty", NULL, "0"); } - if ($question->getExtraInfo()->getPenalty()) { + if ($question->getExtraInfo()->getPenalty()) + { $a_xml_writer->xmlElement("hidden", NULL, $question->getExtraInfo()->getHidden()); - } else { + } else + { $a_xml_writer->xmlElement("hidden", NULL, "0"); } @@ -148,136 +155,173 @@ function toMoodleXML() $a_xml_writer->xmlElement("variantsselectionseed", NULL, $question->getOptions()->getVariantsSelectionSeeds()); //Inputs - if (sizeof($question->getInputs())) { - foreach ($question->getInputs() as $input) { - $a_xml_writer->xmlStartTag("input"); - - $a_xml_writer->xmlElement("name", NULL, $input->getInputName()); - $a_xml_writer->xmlElement("type", NULL, $input->getInputType()); - $a_xml_writer->xmlElement("tans", NULL, $input->getTeacherAnswer()); - $a_xml_writer->xmlElement("boxsize", NULL, $input->getBoxSize()); - $a_xml_writer->xmlElement("strictsyntax", NULL, (int)$input->getStrictSyntax()); - $a_xml_writer->xmlElement("insertstars", NULL, (int)$input->getInsertStars()); - $a_xml_writer->xmlElement("syntaxhint", NULL, $input->getSyntaxHint()); - $a_xml_writer->xmlElement("forbidwords", NULL, $input->getForbidWords()); - $a_xml_writer->xmlElement("allowwords", NULL, $input->getAllowWords()); - $a_xml_writer->xmlElement("forbidfloat", NULL, (int)$input->getForbidFloat()); - $a_xml_writer->xmlElement("requirelowestterms", NULL, (int)$input->getRequireLowestTerms()); - $a_xml_writer->xmlElement("checkanswertype", NULL, (int)$input->getCheckAnswerType()); - $a_xml_writer->xmlElement("mustverify", NULL, (int)$input->getMustVerify()); - $a_xml_writer->xmlElement("showvalidation", NULL, (int)$input->getShowValidation()); - $a_xml_writer->xmlElement("options", NULL, $input->getOptions()); - - $a_xml_writer->xmlEndTag("input"); + if (is_array($question->getInputs())) + { + if (sizeof($question->getInputs())) + { + foreach ($question->getInputs() as $input) + { + $a_xml_writer->xmlStartTag("input"); + + $a_xml_writer->xmlElement("name", NULL, $input->getInputName()); + $a_xml_writer->xmlElement("type", NULL, $input->getInputType()); + $a_xml_writer->xmlElement("tans", NULL, $input->getTeacherAnswer()); + $a_xml_writer->xmlElement("boxsize", NULL, $input->getBoxSize()); + $a_xml_writer->xmlElement("strictsyntax", NULL, (int)$input->getStrictSyntax()); + $a_xml_writer->xmlElement("insertstars", NULL, (int)$input->getInsertStars()); + $a_xml_writer->xmlElement("syntaxhint", NULL, $input->getSyntaxHint()); + $a_xml_writer->xmlElement("forbidwords", NULL, $input->getForbidWords()); + $a_xml_writer->xmlElement("allowwords", NULL, $input->getAllowWords()); + $a_xml_writer->xmlElement("forbidfloat", NULL, (int)$input->getForbidFloat()); + $a_xml_writer->xmlElement("requirelowestterms", NULL, (int)$input->getRequireLowestTerms()); + $a_xml_writer->xmlElement("checkanswertype", NULL, (int)$input->getCheckAnswerType()); + $a_xml_writer->xmlElement("mustverify", NULL, (int)$input->getMustVerify()); + $a_xml_writer->xmlElement("showvalidation", NULL, (int)$input->getShowValidation()); + $a_xml_writer->xmlElement("options", NULL, $input->getOptions()); + + $a_xml_writer->xmlEndTag("input"); + } } } + //PRT - if (sizeof($question->getPotentialResponsesTrees())) { - foreach ($question->getPotentialResponsesTrees() as $prt) { - $a_xml_writer->xmlStartTag("prt"); - - $a_xml_writer->xmlElement("name", NULL, $prt->getPRTName()); - $a_xml_writer->xmlElement("value", NULL, $prt->getPRTValue()); - $a_xml_writer->xmlElement("autosimplify", NULL, $prt->getAutoSimplify()); - - $a_xml_writer->xmlStartTag("feedbackvariables", array("format" => "html")); - $a_xml_writer->xmlElement("text", NULL, $prt->getPRTFeedbackVariables()); - $a_xml_writer->xmlEndTag("feedbackvariables"); - - //Nodes - if (sizeof($prt->getPRTNodes())) { - foreach ($prt->getPRTNodes() as $node) { - $a_xml_writer->xmlStartTag("node"); - - $a_xml_writer->xmlElement("name", NULL, $node->getNodeName()); - $a_xml_writer->xmlElement("answertest", NULL, $node->getAnswerTest()); - $a_xml_writer->xmlElement("sans", NULL, $node->getStudentAnswer()); - $a_xml_writer->xmlElement("tans", NULL, $node->getTeacherAnswer()); - $a_xml_writer->xmlElement("testoptions", NULL, $node->getTestOptions()); - $a_xml_writer->xmlElement("quiet", NULL, $node->getQuiet()); - - $a_xml_writer->xmlElement("truescoremode", NULL, $node->getTrueScoreMode()); - $a_xml_writer->xmlElement("truescore", NULL, $node->getTrueScore()); - $a_xml_writer->xmlElement("truepenalty", NULL, $node->getTruePenalty()); - $a_xml_writer->xmlElement("truenextnode", NULL, $node->getTrueNextNode()); - $a_xml_writer->xmlElement("trueanswernote", NULL, $node->getTrueAnswerNote()); - - $a_xml_writer->xmlStartTag("truefeedback", array("format" => "html")); - $media = $this->getRTEMedia($node->getTrueFeedback()); - $this->addRTEText($a_xml_writer, $node->getTrueFeedback()); - $this->addRTEMedia($a_xml_writer, $media); - $a_xml_writer->xmlEndTag("truefeedback"); - - $a_xml_writer->xmlElement("falsescoremode", NULL, $node->getFalseScoreMode()); - $a_xml_writer->xmlElement("falsescore", NULL, $node->getFalseScore()); - $a_xml_writer->xmlElement("falsepenalty", NULL, $node->getFalsePenalty()); - $a_xml_writer->xmlElement("falsenextnode", NULL, $node->getFalseNextNode()); - $a_xml_writer->xmlElement("falseanswernote", NULL, $node->getFalseAnswerNote()); - - $a_xml_writer->xmlStartTag("falsefeedback", array("format" => "html")); - $media = $this->getRTEMedia($node->getFalseFeedback()); - $this->addRTEText($a_xml_writer, $node->getFalseFeedback()); - $this->addRTEMedia($a_xml_writer, $media); - $a_xml_writer->xmlEndTag("falsefeedback"); - - $a_xml_writer->xmlEndTag("node"); + if (is_array($question->getPotentialResponsesTrees())) + { + if (sizeof($question->getPotentialResponsesTrees())) + { + foreach ($question->getPotentialResponsesTrees() as $prt) + { + $a_xml_writer->xmlStartTag("prt"); + + $a_xml_writer->xmlElement("name", NULL, $prt->getPRTName()); + $a_xml_writer->xmlElement("value", NULL, $prt->getPRTValue()); + $a_xml_writer->xmlElement("autosimplify", NULL, $prt->getAutoSimplify()); + + $a_xml_writer->xmlStartTag("feedbackvariables", array("format" => "html")); + $a_xml_writer->xmlElement("text", NULL, $prt->getPRTFeedbackVariables()); + $a_xml_writer->xmlEndTag("feedbackvariables"); + + //Nodes + if (sizeof($prt->getPRTNodes())) + { + foreach ($prt->getPRTNodes() as $node) + { + $a_xml_writer->xmlStartTag("node"); + + $a_xml_writer->xmlElement("name", NULL, $node->getNodeName()); + $a_xml_writer->xmlElement("answertest", NULL, $node->getAnswerTest()); + $a_xml_writer->xmlElement("sans", NULL, $node->getStudentAnswer()); + $a_xml_writer->xmlElement("tans", NULL, $node->getTeacherAnswer()); + $a_xml_writer->xmlElement("testoptions", NULL, $node->getTestOptions()); + $a_xml_writer->xmlElement("quiet", NULL, $node->getQuiet()); + + $a_xml_writer->xmlElement("truescoremode", NULL, $node->getTrueScoreMode()); + $a_xml_writer->xmlElement("truescore", NULL, $node->getTrueScore()); + $a_xml_writer->xmlElement("truepenalty", NULL, $node->getTruePenalty()); + $a_xml_writer->xmlElement("truenextnode", NULL, $node->getTrueNextNode()); + $a_xml_writer->xmlElement("trueanswernote", NULL, $node->getTrueAnswerNote()); + $a_xml_writer->xmlElement("truefeedbackformat", NULL, $node->getTrueFeedbackFormat()); + + $a_xml_writer->xmlStartTag("truefeedback", array("format" => "html")); + $media = $this->getRTEMedia($node->getTrueFeedback()); + $this->addRTEText($a_xml_writer, $node->getTrueFeedback()); + $this->addRTEMedia($a_xml_writer, $media); + $a_xml_writer->xmlEndTag("truefeedback"); + + $a_xml_writer->xmlElement("falsescoremode", NULL, $node->getFalseScoreMode()); + $a_xml_writer->xmlElement("falsescore", NULL, $node->getFalseScore()); + $a_xml_writer->xmlElement("falsepenalty", NULL, $node->getFalsePenalty()); + $a_xml_writer->xmlElement("falsenextnode", NULL, $node->getFalseNextNode()); + $a_xml_writer->xmlElement("falseanswernote", NULL, $node->getFalseAnswerNote()); + $a_xml_writer->xmlElement("falsefeedbackformat", NULL, $node->getFalseFeedbackFormat()); + + + $a_xml_writer->xmlStartTag("falsefeedback", array("format" => "html")); + $media = $this->getRTEMedia($node->getFalseFeedback()); + $this->addRTEText($a_xml_writer, $node->getFalseFeedback()); + $this->addRTEMedia($a_xml_writer, $media); + $a_xml_writer->xmlEndTag("falsefeedback"); + + $a_xml_writer->xmlEndTag("node"); + } } + $a_xml_writer->xmlEndTag("prt"); } - $a_xml_writer->xmlEndTag("prt"); } } + //deployed seeds - if (sizeof($question->getDeployedSeeds())) { - foreach ($question->getDeployedSeeds() as $seed) { - $a_xml_writer->xmlElement("deployedseed", NULL, $seed->getSeed()); + if (is_array($question->getDeployedSeeds())) + { + if (sizeof($question->getDeployedSeeds())) + { + foreach ($question->getDeployedSeeds() as $seed) + { + $a_xml_writer->xmlElement("deployedseed", NULL, $seed->getSeed()); + } } } + //tests - if (sizeof($question->getTests())) { - foreach ($question->getTests() as $test) { - $a_xml_writer->xmlStartTag("qtest"); - $a_xml_writer->xmlElement("testcase", NULL, $test->getTestCase()); - //test input - foreach ($test->getTestInputs() as $test_input) { - $a_xml_writer->xmlStartTag("testinput"); - $a_xml_writer->xmlElement("name", NULL, $test_input->getTestInputName()); - $a_xml_writer->xmlElement("value", NULL, $test_input->getTestInputValue()); - $a_xml_writer->xmlEndTag("testinput"); - } - //test expected - foreach ($test->getTestExpected() as $test_input) { - $a_xml_writer->xmlStartTag("expected"); - $a_xml_writer->xmlElement("name", NULL, $test_input->getTestPRTName()); - $a_xml_writer->xmlElement("expectedscore", NULL, $test_input->getExpectedScore()); - $a_xml_writer->xmlElement("expectedpenalty", NULL, $test_input->getExpectedPenalty()); - $a_xml_writer->xmlElement("expectedanswernote", NULL, $test_input->getExpectedAnswerNote()); - $a_xml_writer->xmlEndTag("expected"); + if (is_array($question->getTests())) + { + if (sizeof($question->getTests())) + { + foreach ($question->getTests() as $test) + { + $a_xml_writer->xmlStartTag("qtest"); + $a_xml_writer->xmlElement("testcase", NULL, $test->getTestCase()); + //test input + foreach ($test->getTestInputs() as $test_input) + { + $a_xml_writer->xmlStartTag("testinput"); + $a_xml_writer->xmlElement("name", NULL, $test_input->getTestInputName()); + $a_xml_writer->xmlElement("value", NULL, $test_input->getTestInputValue()); + $a_xml_writer->xmlEndTag("testinput"); + } + //test expected + foreach ($test->getTestExpected() as $test_input) + { + $a_xml_writer->xmlStartTag("expected"); + $a_xml_writer->xmlElement("name", NULL, $test_input->getTestPRTName()); + $a_xml_writer->xmlElement("expectedscore", NULL, $test_input->getExpectedScore()); + $a_xml_writer->xmlElement("expectedpenalty", NULL, $test_input->getExpectedPenalty()); + $a_xml_writer->xmlElement("expectedanswernote", NULL, $test_input->getExpectedAnswerNote()); + $a_xml_writer->xmlEndTag("expected"); + } + $a_xml_writer->xmlEndTag("qtest"); } - $a_xml_writer->xmlEndTag("qtest"); } } + $a_xml_writer->xmlEndTag("question"); } $a_xml_writer->xmlEndTag("quiz"); $xml = $a_xml_writer->xmlDumpMem(FALSE); - if (sizeof($this->getStackQuestions()) > 1) { - ilUtil::deliverData($xml, "stack_question_" . $question_id . "_and_others.xml", "xml"); - } elseif (sizeof($this->getStackQuestions()) == 1) { - ilUtil::deliverData($xml, "stack_question_" . $question_id . ".xml", "xml"); + if (is_array($this->getStackQuestions())) + { + if (sizeof($this->getStackQuestions()) > 1) + { + ilUtil::deliverData($xml, "stack_question_" . $question_id . "_and_others.xml", "xml"); + } elseif (sizeof($this->getStackQuestions()) == 1) + { + ilUtil::deliverData($xml, "stack_question_" . $question_id . ".xml", "xml"); + } } + return $xml; } /** * Get the media files used in an RTE text - * @param string text to analyze - * @param assStackQuestion question - * @return array name => file content + * @param string text to analyze + * @param assStackQuestion question + * @return array name => file content */ private function getRTEMedia($a_text, $stack_question = "") { @@ -290,30 +334,30 @@ private function getRTEMedia($a_text, $stack_question = "") $id = $matches[1][$i]; $name = $matches[2][$i]; - $new_match =explode('?',$name); + $new_match = explode('?', $name); - if (is_file(ilUtil::getWebspaceDir()."/mobs/mm_".$id.'/'.$new_match[0])) + if (is_file(ilUtil::getWebspaceDir() . "/mobs/mm_" . $id . '/' . $new_match[0])) { - $media[$new_match[0]] = file_get_contents(ilUtil::getWebspaceDir()."/mobs/mm_".$id.'/'.$new_match[0]); + $media[$new_match[0]] = file_get_contents(ilUtil::getWebspaceDir() . "/mobs/mm_" . $id . '/' . $new_match[0]); } } + return $media; } /** * Add an RTE text * This will change the media references and wrap the text in CDATA - * @param ilXmlWriter XML writer - * @param string text to add - * @param string tag for the element - * @param array attributes + * @param ilXmlWriter XML writer + * @param string text to add + * @param string tag for the element + * @param array attributes */ private function addRTEText($a_xml_writer, $a_text, $a_tag = 'text', $a_attr = null) { - $text = preg_replace( - '/src=".*\/mobs\/mm_([0-9]+)\/([^"]+)"/', 'src="@@PLUGINFILE@@/$2"', $a_text); + $text = preg_replace('/src=".*\/mobs\/mm_([0-9]+)\/([^"]+)"/', 'src="@@PLUGINFILE@@/$2"', $a_text); - $text = ''; + $text = ''; $a_xml_writer->xmlElement($a_tag, NULL, $text, false, false); } @@ -321,19 +365,15 @@ private function addRTEText($a_xml_writer, $a_text, $a_tag = 'text', $a_attr = n /** * Add media files as elements - * @param ilXmlWriter XML writer - * @param array name => content - * @param string tag for the element + * @param ilXmlWriter XML writer + * @param array name => content + * @param string tag for the element */ - private function addRTEMedia($a_xml_writer, $a_media, $a_tag = 'file') + private function addRTEMedia($a_xml_writer, $a_media, $a_tag = 'file') { foreach ($a_media as $name => $content) { - $attr = array ( - 'name' => $name, - 'path' => '/', - 'encoding' => 'base64' - ); + $attr = array('name' => $name, 'path' => '/', 'encoding' => 'base64'); $a_xml_writer->xmlElement('file', $attr, base64_encode($content), false, false); } } diff --git a/classes/model/class.assStackQuestionStackQuestion.php b/classes/model/class.assStackQuestionStackQuestion.php index ca15248d..fe0064d6 100644 --- a/classes/model/class.assStackQuestionStackQuestion.php +++ b/classes/model/class.assStackQuestionStackQuestion.php @@ -271,7 +271,7 @@ public function createSeed($ilias_question, $seed = -1, $authorized = TRUE) global $DIC; $lng = $DIC->language(); - switch (sizeof($ilias_question->getDeployedSeeds())) + switch (!empty($ilias_question->getDeployedSeeds())) { //No deployed seeds for this question. case 0: @@ -442,7 +442,7 @@ public function createInputs(assStackQuestion $question) $stack_inputs[$input_name] = $this->getStackFactory()->get("input_object", $input_parameters); } - if (sizeof($stack_inputs)) + if (!empty($stack_inputs)) { $this->setInputs($stack_inputs); } @@ -469,10 +469,7 @@ public function addTeacherAnswersToSession(assStackQuestion $question) $response[$name] = $teacher_answer_casstring; } } - $session = $this->getSession(); - $session->add_vars($response); - $session->instantiate(); - $this->setSession($session); + $this->getSession()->add_vars($response); } /** diff --git a/classes/model/configuration/class.assStackQuestionConfig.php b/classes/model/configuration/class.assStackQuestionConfig.php index a20b400f..daad6db5 100644 --- a/classes/model/configuration/class.assStackQuestionConfig.php +++ b/classes/model/configuration/class.assStackQuestionConfig.php @@ -15,11 +15,11 @@ */ class assStackQuestionConfig { - /** @var assStackQuestionServer */ - protected static $server; + /** @var assStackQuestionServer */ + protected static $server; - /** @var array */ - protected $settings; + /** @var array */ + protected $settings; public function __construct($plugin_object = "") @@ -32,19 +32,20 @@ public function __construct($plugin_object = "") */ - /** - * Get a configuration setting - * @param $name - * @return mixed - */ - public function get($name) - { - if (!isset($this->settings)) - { - $this->settings = self::_getStoredSettings('all'); - } - return $this->settings[$name]; - } + /** + * Get a configuration setting + * @param $name + * @return mixed + */ + public function get($name) + { + if (!isset($this->settings)) + { + $this->settings = self::_getStoredSettings('all'); + } + + return $this->settings[$name]; + } /** * This class can be called from anywhere to get configuration @@ -73,64 +74,66 @@ public static function _getStoredSettings($selector) } - /** - * Read the server configuration from a configuration array - * This avoids a second reading - * @param $config - */ + /** + * Read the server configuration from a configuration array + * This avoids a second reading + * @param $config + */ public static function _readServers($config) - { - require_once (__DIR__ . '/class.assStackQuestionServer.php'); - assStackQuestionServer::readServersFromConfig($config); - } - - - /** - * Get the maxima server address for the current request - * The chosen server is cached for the request - * - * @return string - */ - public static function _getServerAddress() - { - require_once (__DIR__ . '/class.assStackQuestionServer.php'); - - if (isset(self::$server)) - { - return self::$server->getAddress(); - } - - if (!empty($_REQUEST['server_id'])) - { - self::$server = assStackQuestionServer::getServerById($_REQUEST['server_id']); - return self::$server->getAddress(); - - } - - switch (strtolower($_GET['cmdClass'])) - { - case 'iltestplayerfixedquestionsetgui': - case 'iltestplayerrandomquestionsetgui': - case 'iltestplayerdynamicquestionsetgui': - $purpose = assStackQuestionServer::PURPOSE_RUN; - break; - - default: - switch (basename($_SERVER['SCRIPT_FILENAME'])) - { - case 'validation.php': - case 'instant_validiation.php': - $purpose= assStackQuestionServer::PURPOSE_RUN; - break; - default: - $purpose = assStackQuestionServer::PURPOSE_EDIT; - } - } - - - self::$server = assStackQuestionServer::getServerForPurpose($purpose); - return self::$server->getAddress(); - } + { + require_once(__DIR__ . '/class.assStackQuestionServer.php'); + assStackQuestionServer::readServersFromConfig($config); + } + + + /** + * Get the maxima server address for the current request + * The chosen server is cached for the request + * + * @return string + */ + public static function _getServerAddress() + { + require_once(__DIR__ . '/class.assStackQuestionServer.php'); + + if (isset(self::$server)) + { + return self::$server->getAddress(); + } + + if (!empty($_REQUEST['server_id'])) + { + self::$server = assStackQuestionServer::getServerById($_REQUEST['server_id']); + + return self::$server->getAddress(); + + } + + switch (strtolower($_GET['cmdClass'])) + { + case 'iltestplayerfixedquestionsetgui': + case 'iltestplayerrandomquestionsetgui': + case 'iltestplayerdynamicquestionsetgui': + $purpose = assStackQuestionServer::PURPOSE_RUN; + break; + + default: + switch (basename($_SERVER['SCRIPT_FILENAME'])) + { + case 'validation.php': + case 'instant_validiation.php': + $purpose = assStackQuestionServer::PURPOSE_RUN; + break; + default: + $purpose = assStackQuestionServer::PURPOSE_EDIT; + } + } + + + self::$server = assStackQuestionServer::getServerForPurpose($purpose); + + return self::$server->getAddress(); + } /* @@ -317,6 +320,42 @@ public function saveDefaultInputsSettings() return TRUE; } + public function saveFeedbackStyleSettings() + { + //Old settings + $saved_feedback_data = self::_getStoredSettings('feedback'); + //New settings + $new_feedback_data = $this->getAdminInput(); + + //Check if Content Style has changed, if changed set pther fields to 0, otherwise, save it with new values + if ($saved_feedback_data["feedback_stylesheet_id"] != $new_feedback_data["feedback_stylesheet_id"]) + { + //Save to DB + foreach ($saved_feedback_data as $parameter_name => $saved_value) + { + if ($parameter_name != "feedback_stylesheet_id") + { + $this->saveToDB($parameter_name, "0", 'feedback'); + } else + { + $this->saveToDB($parameter_name, $new_feedback_data[$parameter_name], 'feedback'); + } + } + } else + { + //Save to DB modified dat + foreach ($saved_feedback_data as $paremeter_name => $saved_value) + { + if (array_key_exists($paremeter_name, $new_feedback_data) AND $saved_feedback_data[$paremeter_name] != $new_feedback_data[$paremeter_name]) + { + $this->saveToDB($paremeter_name, $new_feedback_data[$paremeter_name], 'feedback'); + } + } + } + + return TRUE; + } + /** * Saves new default inputs settings to the DB */ @@ -390,9 +429,9 @@ public function saveDefaultPRTsSettings() } /** - * Save a configuration setting to the database - * (needs to be public for assStackQuestionServer::saveServers) - * + * Save a configuration setting to the database + * (needs to be public for assStackQuestionServer::saveServers) + * * @param $parameter_name //Is the of the parameter to modify (this is the Primary Key in DB) * @param $value //Is the value of the parameter * @param $group_name //Is the selector for different categories of data @@ -413,7 +452,8 @@ public function saveToDB($parameter_name, $value, $group_name) */ public function getAdminInput() { - $data = ilUtil::stripSlashesRecursive($_POST); + //https://mantis.ilias.de/view.php?id=25290 + $data = ilUtil::stripSlashesRecursive($_POST, FALSE); //Clean array unset($data['cmd']); diff --git a/classes/model/configuration/class.assStackQuestionHealthcheck.php b/classes/model/configuration/class.assStackQuestionHealthcheck.php index 706926b0..291b3e54 100644 --- a/classes/model/configuration/class.assStackQuestionHealthcheck.php +++ b/classes/model/configuration/class.assStackQuestionHealthcheck.php @@ -80,7 +80,7 @@ public function checkMaximaConnection() //texdisplaystyle $this->setMaximaConnectionStatus(html_writer::tag('p', stack_string('texdisplaystyle')), 'texdisplaystyle'); //healthchecksampledisplaytex - $this->setMaximaConnectionStatus(html_writer::tag('p', stack_string('healthchecksampledisplaytex')), 'healthchecksampledisplaytex'); + $this->setMaximaConnectionStatus(html_writer::tag('p', assStackQuestionUtils::_solveKeyBracketsBug(stack_string('healthchecksampledisplaytex'))), 'healthchecksampledisplaytex'); //texinlinestyle $this->setMaximaConnectionStatus(html_writer::tag('p', stack_string('texinlinestyle')), 'texinlinestyle'); //healthchecksampleinlinetex @@ -88,6 +88,7 @@ public function checkMaximaConnection() //healthchecklatexmathjax $this->setMaximaConnectionStatus(html_writer::tag('p', stack_string('healthchecklatexmathjax')), 'healthchecklatexmathjax'); + //Maxima configuration file // Try to list available versions of Maxima (linux only, without the DB). if ($this->config->platform !== 'win') diff --git a/classes/model/ilias_object/class.assStackQuestionPRTNode.php b/classes/model/ilias_object/class.assStackQuestionPRTNode.php index c0219af9..16d0f009 100644 --- a/classes/model/ilias_object/class.assStackQuestionPRTNode.php +++ b/classes/model/ilias_object/class.assStackQuestionPRTNode.php @@ -442,6 +442,7 @@ public function writePostData($prt_name, $node_name, $new_prt_name = "", $new_no $this->setTrueNextNode(ilUtil::stripSlashes($_POST[$prefix . '_pos_next'])); $this->setTrueAnswerNote(ilUtil::stripSlashes($_POST[$prefix . '_pos_answernote'] == NULL ? "" : $_POST[$prefix . '_pos_answernote'])); $this->setTrueFeedback(ilUtil::stripSlashes($_POST[$prefix . '_pos_specific_feedback'] == NULL ? "" : $_POST[$prefix . '_pos_specific_feedback'], true, $a_rte_tags)); + $this->setTrueFeedbackFormat(ilUtil::stripSlashes($_POST[$prefix . '_pos_feedback_class'])); $this->setFalseScore(ilUtil::stripSlashes($_POST[$prefix . '_neg_score']) == NULL ? 0 : ilUtil::stripSlashes($_POST[$prefix . '_neg_score'])); $this->setFalseScoreMode(ilUtil::stripSlashes($_POST[$prefix . '_neg_mod'])); @@ -449,6 +450,7 @@ public function writePostData($prt_name, $node_name, $new_prt_name = "", $new_no $this->setFalseNextNode(ilUtil::stripSlashes($_POST[$prefix . '_neg_next'])); $this->setFalseAnswerNote(ilUtil::stripSlashes($_POST[$prefix . '_neg_answernote'] == NULL ? "" : $_POST[$prefix . '_neg_answernote'])); $this->setFalseFeedback(ilUtil::stripSlashes($_POST[$prefix . '_neg_specific_feedback'] == NULL ? "" : $_POST[$prefix . '_neg_specific_feedback'], true, $a_rte_tags)); + $this->setFalseFeedbackFormat(ilUtil::stripSlashes($_POST[$prefix . '_neg_feedback_class'])); if ($new_prt_name) { diff --git a/classes/model/ilias_object/test/class.assStackQuestionTest.php b/classes/model/ilias_object/test/class.assStackQuestionTest.php index 776b7851..36974198 100644 --- a/classes/model/ilias_object/test/class.assStackQuestionTest.php +++ b/classes/model/ilias_object/test/class.assStackQuestionTest.php @@ -153,7 +153,7 @@ public static function _read($question_id, $test_case = '') //Reading test data $test->setTestInputs(assStackQuestionTestInput::_read($question_id, $test->getTestCase())); $test->setTestExpected(assStackQuestionTestExpected::_read($question_id, $test->getTestCase())); - $test->setNumberOfTests(sizeof($test->getTestInputs())); + $test->setNumberOfTests(!empty($test->getTestInputs())); $tests[$test->getTestCase()] = $test; } @@ -203,7 +203,7 @@ public function checkTest($solve_problems = TRUE) return false; } //Arrays filled in: - if (sizeof($this->getTestInputs()) AND sizeof($this->getTestExpected())) { + if (!empty($this->getTestInputs()) AND sizeof($this->getTestExpected())) { return true; } } diff --git a/classes/model/import/MoodleXML/class.assStackQuestionMoodleImport.php b/classes/model/import/MoodleXML/class.assStackQuestionMoodleImport.php index 4a56b987..3ece33cb 100644 --- a/classes/model/import/MoodleXML/class.assStackQuestionMoodleImport.php +++ b/classes/model/import/MoodleXML/class.assStackQuestionMoodleImport.php @@ -96,6 +96,13 @@ public function importQuestions($raw_data) { $number_of_questions_created = 0; //For each question in the array + + //Check if is PHP 7.2 in case it is, data need some extra formatting + if (assStackQuestionUtils::_isPhP72()) + { + $raw_data = $this->php72Format($raw_data['question']); + } + foreach ($raw_data['question'] as $data) { // start with a new list of media objects for each question @@ -193,7 +200,7 @@ public function importQuestions($raw_data) $this->purgeMediaObjects(); } } - if (sizeof($this->error_log)) + if (!empty($this->error_log)) { ilUtil::sendFailure(implode('
', $this->error_log)); } @@ -286,7 +293,7 @@ private function cleanXML($xml_data) { foreach ($xml_data as $array) { - if (sizeof($array) > 1) + if (!empty($array)) { return $array; } @@ -575,7 +582,13 @@ private function getPRTNodesFromXML($data, $prt_name) $new_node->setTrueScore(strip_tags($prt_node['truescore'])); $new_node->setTruePenalty(strip_tags($prt_node['truepenalty'])); $new_node->setTrueAnswerNote($prt_node['trueanswernote']); - $new_node->setTrueFeedbackFormat(1); + if (isset($prt_node['truefeedbackformat'])) + { + $new_node->setTrueFeedbackFormat($prt_node['truefeedbackformat']); + } else + { + $new_node->setTrueFeedbackFormat(1); + } $mapping = $this->getMediaObjectsFromXML($prt_node['truefeedback'][0]['file']); $truefeedback = assStackQuestionUtils::_casTextConverter($this->replaceMediaObjectReferences($prt_node['truefeedback'][0]['text'], $mapping), $this->getQuestion()->getTitle(), TRUE); @@ -586,7 +599,13 @@ private function getPRTNodesFromXML($data, $prt_name) $new_node->setFalseScore(strip_tags($prt_node['falsescore'])); $new_node->setFalsePenalty(strip_tags($prt_node['falsepenalty'])); $new_node->setFalseAnswerNote($prt_node['falseanswernote']); - $new_node->setFalseFeedbackFormat(1); + if (isset($prt_node['falsefeedbackformat'])) + { + $new_node->setFalseFeedbackFormat($prt_node['falsefeedbackformat']); + } else + { + $new_node->setFalseFeedbackFormat(1); + } $mapping = $this->getMediaObjectsFromXML($prt_node['falsefeedback'][0]['file']); $falsefeedback = assStackQuestionUtils::_casTextConverter($this->replaceMediaObjectReferences($prt_node['falsefeedback'][0]['text'], $mapping), $this->getQuestion()->getTitle(), TRUE); @@ -709,7 +728,7 @@ private function getExtraInfoFromXML($data) /** * Create media objects from array converted file elements - * @param array $data [['_attributes' => ['name' => string, 'path' => string], '_content' => string], ...] + * @param array $data [['_attributes' => ['name' => string, 'path' => string], '_content' => string], ...] * @return array filename => object_id */ private function getMediaObjectsFromXML($data = array()) @@ -735,8 +754,8 @@ private function getMediaObjectsFromXML($data = array()) /** * Replace references to media objects in a text - * @param string text from moodleXML with local references - * @param array mapping of filenames to media object IDs + * @param string text from moodleXML with local references + * @param array mapping of filenames to media object IDs * @return string text with paths to media objects */ private function replaceMediaObjectReferences($text = "", $mapping = array()) @@ -874,7 +893,7 @@ public function checkQuestion(assStackQuestion $question) } //Step 5: Check tests - if (sizeof($question->getTests())) + if (!empty($question->getTests())) { foreach ($question->getTests() as $test) { @@ -992,4 +1011,631 @@ public function getRTETags() { return $this->rte_tags; } + + public function php72Format($raw_data) + { + $full_data = array(); + + foreach ($raw_data as $question_data) + { + $data = array(); + //Check for not category + if (is_array($question_data['category'])) + { + continue; + } + + //Question Name + $data['name'][0]['text'] = $question_data['name'][0]['text'][0]["_content"]; + + //Question text + $data['questiontext'][0]['text'] = $question_data['questiontext'][0]['text']; + + //General feedback + $data['generalfeedback'][0]['text'] = $question_data['generalfeedback'][0]['text']; + + //default grade + $data['defaultgrade'] = $question_data['defaultgrade'][0]["_content"]; + + //penalty + $data['penalty'] = $question_data['penalty'][0]["_content"]; + + //hidden + if (isset($question_data['hidden'][0]["_content"])) + { + $data['hidden'] = $question_data['hidden'][0]["_content"]; + } else + { + $data['hidden'] = ""; + } + + //stackversion + if (isset($question_data['stackversion'][0]["_content"])) + { + $data['stackversion'][0]['text'] = $question_data['stackversion'][0]['text']; + } else + { + $data['stackversion'][0]['text'] = ""; + } + + //questionvariables 2 versions to solve problems with question variables tarting with comments + if (isset($question_data['questionvariables'][0]['text'][0]['_content'])) + { + $data['questionvariables'][0]['text'] = $question_data['questionvariables'][0]['text'][0]['_content']; + } elseif (isset($question_data['questionvariables'][0]['text']) AND is_string($question_data['questionvariables'][0]['text'])) + { + $data['questionvariables'][0]['text'] = $question_data['questionvariables'][0]['text']; + } else + { + $data['questionvariables'][0]['text'] = ""; + } + + //specificfeedback: + if (isset($question_data['specificfeedback'][0]['text'][0]['_content'])) + { + $data['specificfeedback'][0]['text'] = $question_data['specificfeedback'][0]['text'][0]['_content']; + } elseif (isset($question_data['specificfeedback'][0]['text']) AND is_string($question_data['specificfeedback'][0]['text'])) + { + $data['specificfeedback'][0]['text'] = $question_data['specificfeedback'][0]['text']; + } else + { + $data['specificfeedback'][0]['text'] = ""; + } + + //questionnote + if (isset($question_data['questionnote'][0]['text'][0]['_content'])) + { + $data['questionnote'][0]['text'] = $question_data['questionnote'][0]['text'][0]['_content']; + } elseif (isset($question_data['questionnote'][0]['text']) AND is_string($question_data['questionnote'][0]['text'])) + { + $data['questionnote'][0]['text'] = $question_data['questionnote'][0]['text']; + }else + { + $data['questionnote'][0]['text'] = ""; + } + + //questionsimplify + if (isset($question_data['questionsimplify'][0]["_content"])) + { + $data['questionsimplify'] = $question_data['questionsimplify'][0]["_content"]; + } else + { + $data['questionsimplify'] = ""; + } + + //assumepositive + if (isset($question_data['assumepositive'][0]["_content"])) + { + $data['assumepositive'] = $question_data['assumepositive'][0]["_content"]; + } else + { + $data['assumepositive'] = ""; + } + + //assumereal + if (isset($question_data['assumereal'][0]["_content"])) + { + $data['assumereal'] = $question_data['assumereal'][0]["_content"]; + } else + { + $data['assumereal'] = ""; + } + + //prtcorrect + if (isset($question_data['prtcorrect'][0]["_content"])) + { + $data['prtcorrect'][0]['text'] = $question_data['prtcorrect'][0]['text']; + } else + { + $data['prtcorrect'][0]['text'] = ""; + } + + //prtpartiallycorrect + if (isset($question_data['prtpartiallycorrect'][0]["_content"])) + { + $data['prtpartiallycorrect'][0]['text'] = $question_data['prtpartiallycorrect'][0]['text']; + } else + { + $data['prtpartiallycorrect'][0]['text'] = ""; + } + + //prtincorrect + if (isset($question_data['prtincorrect'][0]["_content"])) + { + $data['prtincorrect'][0]['text'] = $question_data['prtincorrect'][0]['text']; + } else + { + $data['prtincorrect'][0]['text'] = ""; + } + + //multiplicationsign + if (isset($question_data['multiplicationsign'][0]["_content"])) + { + $data['multiplicationsign'] = $question_data['multiplicationsign'][0]["_content"]; + } else + { + $data['multiplicationsign'] = ""; + } + + //sqrtsign + if (isset($question_data['sqrtsign'][0]["_content"])) + { + $data['sqrtsign'] = $question_data['sqrtsign'][0]["_content"]; + } else + { + $data['sqrtsign'] = ""; + } + + //complexno + if (isset($question_data['complexno'][0]["_content"])) + { + $data['complexno'] = $question_data['complexno'][0]["_content"]; + } else + { + $data['complexno'] = ""; + } + + //inversetrig + if (isset($question_data['inversetrig'][0]["_content"])) + { + $data['inversetrig'] = $question_data['inversetrig'][0]["_content"]; + } else + { + $data['inversetrig'] = ""; + } + + //matrixparens + if (isset($question_data['matrixparens'][0]["_content"])) + { + $data['matrixparens'] = $question_data['matrixparens'][0]["_content"]; + } else + { + $data['matrixparens'] = ""; + } + + //variantsselectionseed + if (isset($question_data['variantsselectionseed'])) + { + $data['variantsselectionseed'] = $question_data['variantsselectionseed']; + } else + { + $data['variantsselectionseed'] = ""; + } + + //Inputs + if (is_array($question_data['input'])) + { + foreach ($question_data['input'] as $input_raw) + { + $input_data = array(); + + //name + if (isset($input_raw['name'][0]["_content"])) + { + $input_data['name'] = $input_raw['name'][0]["_content"]; + } else + { + $input_data['name'] = ""; + } + + //type + if (isset($input_raw['type'][0]["_content"])) + { + $input_data['type'] = $input_raw['type'][0]["_content"]; + } else + { + $input_data['type'] = ""; + } + + //tans + if (isset($input_raw['tans'][0]["_content"])) + { + $input_data['tans'] = $input_raw['tans'][0]["_content"]; + } else + { + $input_data['tans'] = ""; + } + + //boxsize + if (isset($input_raw['boxsize'][0]["_content"])) + { + $input_data['boxsize'] = $input_raw['boxsize'][0]["_content"]; + } else + { + $input_data['boxsize'] = ""; + } + + //strictsyntax + if (isset($input_raw['strictsyntax'][0]["_content"])) + { + $input_data['strictsyntax'] = $input_raw['strictsyntax'][0]["_content"]; + } else + { + $input_data['strictsyntax'] = ""; + } + + //insertstars + if (isset($input_raw['insertstars'][0]["_content"])) + { + $input_data['insertstars'] = $input_raw['insertstars'][0]["_content"]; + } else + { + $input_data['insertstars'] = ""; + } + + //syntaxhint + if (isset($input_raw['syntaxhint'][0]["_content"])) + { + $input_data['syntaxhint'] = $input_raw['syntaxhint'][0]["_content"]; + } else + { + $input_data['syntaxhint'] = ""; + } + + //syntaxattribute + if (isset($input_raw['syntaxattribute'][0]["_content"])) + { + $input_data['syntaxattribute'] = $input_raw['syntaxattribute'][0]["_content"]; + } else + { + $input_data['syntaxattribute'] = ""; + } + + //forbidwords + if (isset($input_raw['forbidwords'][0]["_content"])) + { + $input_data['forbidwords'] = $input_raw['forbidwords'][0]["_content"]; + } else + { + $input_data['forbidwords'] = ""; + } + + //allowwords + if (isset($input_raw['allowwords'][0]["_content"])) + { + $input_data['allowwords'] = $input_raw['allowwords'][0]["_content"]; + } else + { + $input_data['allowwords'] = ""; + } + + //forbidfloat + if (isset($input_raw['forbidfloat'][0]["_content"])) + { + $input_data['forbidfloat'] = $input_raw['forbidfloat'][0]["_content"]; + } else + { + $input_data['forbidfloat'] = ""; + } + + //requirelowestterms + if (isset($input_raw['requirelowestterms'][0]["_content"])) + { + $input_data['requirelowestterms'] = $input_raw['requirelowestterms'][0]["_content"]; + } else + { + $input_data['requirelowestterms'] = ""; + } + + //checkanswertype + if (isset($input_raw['checkanswertype'][0]["_content"])) + { + $input_data['checkanswertype'] = $input_raw['checkanswertype'][0]["_content"]; + } else + { + $input_data['checkanswertype'] = ""; + } + + //mustverify + if (isset($input_raw['mustverify'][0]["_content"])) + { + $input_data['mustverify'] = $input_raw['mustverify'][0]["_content"]; + } else + { + $input_data['mustverify'] = ""; + } + + //showvalidation + if (isset($input_raw['showvalidation'][0]["_content"])) + { + $input_data['showvalidation'] = $input_raw['showvalidation'][0]["_content"]; + } else + { + $input_data['showvalidation'] = ""; + } + + //options + if (isset($input_raw['options'][0]["_content"])) + { + $input_data['options'] = $input_raw['options'][0]["_content"]; + } else + { + $input_data['options'] = ""; + } + + //Add to question + $data['input'][] = $input_data; + } + } + + //PRT + if (is_array($question_data['prt'])) + { + foreach ($question_data['prt'] as $prt_raw) + { + $prt_data = array(); + + //name + if (isset($prt_raw['name'][0]["_content"])) + { + $prt_data['name'] = $prt_raw['name'][0]["_content"]; + } else + { + $prt_data['name'] = ""; + } + + //value + if (isset($prt_raw['value'][0]["_content"])) + { + $prt_data['value'] = $prt_raw['value'][0]["_content"]; + } else + { + $prt_data['value'] = ""; + } + + //autosimplify + if (isset($prt_raw['autosimplify'][0]["_content"])) + { + $prt_data['autosimplify'] = $prt_raw['autosimplify'][0]["_content"]; + } else + { + $prt_data['autosimplify'] = ""; + } + + //feedbackvariables + if (isset($prt_raw['feedbackvariables'][0]["text"])) + { + $prt_data['feedbackvariables'][0]["text"] = $prt_raw['feedbackvariables'][0]["text"]; + } else + { + $prt_data['feedbackvariables'][0]["text"] = ""; + } + + //Nodes + if (is_array($prt_raw['node'])) + { + foreach ($prt_raw['node'] as $node_raw) + { + $node_data = array(); + + //name + if (isset($node_raw['name'][0]["_content"])) + { + $node_data['name'] = $node_raw['name'][0]["_content"]; + } else + { + $node_data['name'] = ""; + } + + //answertest + if (isset($node_raw['answertest'][0]["_content"])) + { + $node_data['answertest'] = $node_raw['answertest'][0]["_content"]; + } else + { + $node_data['answertest'] = ""; + } + + //sans + if (isset($node_raw['sans'][0]["_content"])) + { + $node_data['sans'] = $node_raw['sans'][0]["_content"]; + } else + { + $node_data['sans'] = ""; + } + + //tans + if (isset($node_raw['tans'][0]["_content"])) + { + $node_data['tans'] = $node_raw['tans'][0]["_content"]; + } else + { + $node_data['tans'] = ""; + } + + //testoptions + if (isset($node_raw['testoptions'][0]["_content"])) + { + $node_data['testoptions'] = $node_raw['testoptions'][0]["_content"]; + } else + { + $node_data['testoptions'] = ""; + } + + //quiet + if (isset($node_raw['quiet'][0]["_content"])) + { + $node_data['quiet'] = $node_raw['quiet'][0]["_content"]; + } else + { + $node_data['quiet'] = ""; + } + + //truescoremode + if (isset($node_raw['truescoremode'][0]["_content"])) + { + $node_data['truescoremode'] = $node_raw['truescoremode'][0]["_content"]; + } else + { + $node_data['truescoremode'] = ""; + } + + //truescore + if (isset($node_raw['truescore'][0]["_content"])) + { + $node_data['truescore'] = $node_raw['truescore'][0]["_content"]; + } else + { + $node_data['truescore'] = ""; + } + + //truepenalty + if (isset($node_raw['truepenalty'][0]["_content"])) + { + $node_data['truepenalty'] = $node_raw['truepenalty'][0]["_content"]; + } else + { + $node_data['truepenalty'] = ""; + } + + //truenextnode + if (isset($node_raw['truenextnode'][0]["_content"])) + { + $node_data['truenextnode'] = $node_raw['truenextnode'][0]["_content"]; + } else + { + $node_data['truenextnode'] = ""; + } + + //trueanswernote + if (isset($node_raw['trueanswernote'][0]["_content"])) + { + $node_data['trueanswernote'] = $node_raw['trueanswernote'][0]["_content"]; + } else + { + $node_data['trueanswernote'] = ""; + } + + //truefeedback + if (isset($node_raw['truefeedback'][0]["text"][0]["_content"])) + { + $node_data['truefeedback'][0]["text"] = $node_raw['truefeedback'][0]["text"][0]["_content"]; + } else + { + $node_data['truefeedback'][0]["text"] = ""; + } + + //falsescoremode + if (isset($node_raw['falsescoremode'][0]["_content"])) + { + $node_data['falsescoremode'] = $node_raw['falsescoremode'][0]["_content"]; + } else + { + $node_data['falsescoremode'] = ""; + } + + //falsescore + if (isset($node_raw['falsescore'][0]["_content"])) + { + $node_data['falsescore'] = $node_raw['falsescore'][0]["_content"]; + } else + { + $node_data['falsescore'] = ""; + } + + //falsepenalty + if (isset($node_raw['falsepenalty'][0]["_content"])) + { + $node_data['falsepenalty'] = $node_raw['falsepenalty'][0]["_content"]; + } else + { + $node_data['falsepenalty'] = ""; + } + + //falsenextnode + if (isset($node_raw['falsenextnode'][0]["_content"])) + { + $node_data['falsenextnode'] = $node_raw['falsenextnode'][0]["_content"]; + } else + { + $node_data['falsenextnode'] = ""; + } + + //falseanswernote + if (isset($node_raw['falseanswernote'][0]["_content"])) + { + $node_data['falseanswernote'] = $node_raw['falseanswernote'][0]["_content"]; + } else + { + $node_data['falseanswernote'] = ""; + } + + //falsefeedback + if (isset($node_raw['falsefeedback'][0]["text"][0]["_content"])) + { + $node_data['falsefeedback'][0]["text"] = $node_raw['falsefeedback'][0]["text"][0]["_content"]; + } else + { + $node_data['falsefeedback'][0]["text"] = ""; + } + + //Add to prt + $prt_data['node'][] = $node_data; + } + } + + //Add to question + $data['prt'][] = $prt_data; + + //qtest + if (is_array($question_data['qtest'])) + { + foreach ($question_data['qtest'] as $qtest_raw) + { + $qtest_data = array(); + + //testcase + if (isset($qtest_raw['testcase'][0]["_content"])) + { + $qtest_data['testcase'] = $qtest_raw['testcase'][0]["_content"]; + } else + { + $qtest_data['testcase'] = ""; + } + + //testinput + if (isset($qtest_raw['testinput'][0]['name'][0]["_content"]) AND isset($qtest_raw['testinput'][0]['value'][0]["_content"])) + { + $qtest_data['testinput'][0]['name'] = $qtest_raw['testinput'][0]['name'][0]["_content"]; + $qtest_data['testinput'][0]['value'] = $qtest_raw['testinput'][0]['value'][0]["_content"]; + } else + { + $qtest_data['testinput'][0]['name'] = ""; + $qtest_data['testinput'][0]['value'] = ""; + } + + //expected + if (isset($qtest_raw['expected'][0]['name'][0]["_content"]) AND isset($qtest_raw['expected'][0]['expectedscore'][0]["_content"]) AND isset($qtest_raw['expected'][0]['expectedanswernote'][0]["_content"])) + { + $qtest_data['expected'][0]['name'] = $qtest_raw['expected'][0]['name'][0]["_content"]; + $qtest_data['expected'][0]['expectedscore'] = $qtest_raw['expected'][0]['expectedscore'][0]["_content"]; + $qtest_data['expected'][0]['expectedpenalty'] = $qtest_raw['expected'][0]['expectedpenalty'][0]["_content"]; + $qtest_data['expected'][0]['expectedanswernote'] = $qtest_raw['expected'][0]['expectedanswernote'][0]["_content"]; + + } else + { + $qtest_data['expected'][0]['name'] = ""; + $qtest_data['expected'][0]['expectedscore'] = ""; + $qtest_data['expected'][0]['expectedpenalty'] = ""; + $qtest_data['expected'][0]['expectedanswernote'] = ""; + } + + + //Add to question + $data['qtest'][] = $qtest_data; + } + } + + } + } + + //Add to full data + $full_data['question'][] = $data; + + } + + return $full_data; + } + } diff --git a/classes/model/question_display/class.assStackQuestionDisplay.php b/classes/model/question_display/class.assStackQuestionDisplay.php index 603c1b64..236709fc 100644 --- a/classes/model/question_display/class.assStackQuestionDisplay.php +++ b/classes/model/question_display/class.assStackQuestionDisplay.php @@ -167,12 +167,16 @@ private function replacementForInputPlaceholders($input, $input_name, $in_test, //In assStackQuestionDisplay the User response should be store with the "value" format for assStackQuestionUtils::_getUserResponse. $student_answer = $this->getUserResponse($input_name, $in_test); //Bug https://www.ilias.de/mantis/view.php?id=22129 about matrix syntax hint - if (!sizeof($student_answer) AND ($input->get_parameter('syntaxHint') != '') AND is_a($input, 'stack_matrix_input')) + if (is_array($student_answer)) { - $student_answer = assStackQuestionUtils::_changeUserResponseStyle(array($input_name => $input->get_parameter('syntaxHint')), $this->getQuestion()->getQuestionId(), array($input_name => $input), 'reduced_to_value'); - $student_answer = $student_answer["xqcas_input_" . $input_name . "_value"]; + if (!sizeof($student_answer) AND ($input->get_parameter('syntaxHint') != '') AND is_a($input, 'stack_matrix_input')) + { + $student_answer = assStackQuestionUtils::_changeUserResponseStyle(array($input_name => $input->get_parameter('syntaxHint')), $this->getQuestion()->getQuestionId(), array($input_name => $input), 'reduced_to_value'); + $student_answer = $student_answer["xqcas_input_" . $input_name . "_value"]; + } } + //Create input state if ($in_test) { @@ -187,9 +191,16 @@ private function replacementForInputPlaceholders($input, $input_name, $in_test, //Solve problem with string input type if (is_array($student_answer)) { - if ($student_answer[$input_name] == NULL) + if (get_class($input) == 'stack_matrix_input') + { + //https://mantis.ilias.de/view.php?id=25256 + return $state->contentsdisplayed; + } else { - return ""; + if ($student_answer[$input_name] == NULL) + { + return ""; + } } } @@ -259,19 +270,21 @@ private function replacementForValidationPlaceholders($input, $input_name) private function replacementForPRTPlaceholders($prt, $prt_name, $in_test) { $string = ""; - if (sizeof($this->getInlineFeedback())) + if (!empty($this->getInlineFeedback())) { //feedback - $string .= ''; } - return $string; + + return assStackQuestionUtils::_getFeedbackStyledText($string, "feedback_default"); } /* @@ -469,12 +482,16 @@ public function replacementForValidationInput($input, $input_name, $in_test, $re //In assStackQuestionDisplay the User response should be store with the "value" format for assStackQuestionUtils::_getUserResponse. $student_answer = $this->getUserResponse($input_name, $in_test); //Bug https://www.ilias.de/mantis/view.php?id=22129 about matrix syntax hint - if (!sizeof($student_answer) AND ($input->get_parameter('syntaxHint') != '') AND is_a($input, 'stack_matrix_input')) + if (is_array($student_answer)) { - $student_answer = assStackQuestionUtils::_changeUserResponseStyle(array($input_name => $input->get_parameter('syntaxHint')), $this->getQuestion()->getQuestionId(), array($input_name => $input), 'reduced_to_value'); - $student_answer = $student_answer["xqcas_input_" . $input_name . "_value"]; + if (!sizeof($student_answer) AND ($input->get_parameter('syntaxHint') != '') AND is_a($input, 'stack_matrix_input')) + { + $student_answer = assStackQuestionUtils::_changeUserResponseStyle(array($input_name => $input->get_parameter('syntaxHint')), $this->getQuestion()->getQuestionId(), array($input_name => $input), 'reduced_to_value'); + $student_answer = $student_answer["xqcas_input_" . $input_name . "_value"]; + } } + $input_state = $this->getQuestion()->getInputStates($input_name); $input_size = (string)$input->get_parameter("boxWidth"); @@ -506,7 +523,14 @@ public function replacementForValidationInput($input, $input_name, $in_test, $re for ($j = 0; $j < $matrix_input_columns; $j++) { $user_matrix .= ""; - $user_filled_input = '' . $student_answer[$input_name][$input_name . "_sub_" . $i . "_" . $j] . ''; + //https://mantis.ilias.de/view.php?id=25256 + if ($in_test) + { + $user_filled_input = '' . $student_answer[$input_name][$input_name . "_sub_" . $i . "_" . $j] . ''; + } else + { + $user_filled_input = '' . $student_answer[$input_name . "_sub_" . $i . "_" . $j] . ''; + } $user_matrix .= $user_filled_input; $user_matrix .= ""; } @@ -557,10 +581,7 @@ public function replacementForValidationInput($input, $input_name, $in_test, $re } if (is_a($input, "stack_notes_input")) { - $string = ""; - $string .= ''; + $string = assStackQuestionUtils::_getFeedbackStyledText($this->getPlugin()->txt("notes_best_solution_message"), "feedback_default"); $result["value"] = $string; $result["display"] = ""; diff --git a/classes/model/question_evaluation/class.assStackQuestionFeedback.php b/classes/model/question_evaluation/class.assStackQuestionFeedback.php index 512dbb72..01c69fbf 100644 --- a/classes/model/question_evaluation/class.assStackQuestionFeedback.php +++ b/classes/model/question_evaluation/class.assStackQuestionFeedback.php @@ -91,7 +91,6 @@ private function createPRTFeedback($prt_name, $prt_data) $prt_feedback['status'] = $this->fillStatus($prt_data['state']); //fill answernote $prt_feedback['answernote'] = $this->fillAnswerNote($prt_data['state']); - return $prt_feedback; } @@ -172,8 +171,27 @@ private function fillFeedback($prt_state) { foreach ($prt_state->__get('feedback') as $feedback_obj) { - $feedback .= $prt_state->substitue_variables_in_feedback($feedback_obj->feedback); - $feedback .= '
'; + switch ($feedback_obj->format) + { + case "2": + $feedback .= "[[feedback_node_right]]".$prt_state->substitue_variables_in_feedback($feedback_obj->feedback). "[[feedback_node_right_close]]"; + break; + case "3": + $feedback .= "[[feedback_node_wrong]]".$prt_state->substitue_variables_in_feedback($feedback_obj->feedback). "[[feedback_node_wrong_close]]"; + break; + case "4": + $feedback .= "[[feedback_solution_hint]]".$prt_state->substitue_variables_in_feedback($feedback_obj->feedback). "[[feedback_solution_hint_close]]"; + break; + case "5": + $feedback .= "[[feedback_extra_info]]".$prt_state->substitue_variables_in_feedback($feedback_obj->feedback). "[[feedback_extra_info_close]]"; + break; + case "6": + $feedback .= "[[feedback_plot_feedback]]".$prt_state->substitue_variables_in_feedback($feedback_obj->feedback). "[[feedback_plot_feedback_close]]"; + break; + default: + $feedback .= $prt_state->substitue_variables_in_feedback($feedback_obj->feedback); + break; + } } } @@ -496,10 +514,7 @@ public function getCorrectResponsePlaceholders($input_name = "") } if (is_a($input, "stack_notes_input")) { - $string = ""; - $string .= ''; + $string = assStackQuestionUtils::_getFeedbackStyledText($this->getPlugin()->txt("notes_best_solution_message"), "feedback_default"); $result["value"] = $string; $result["display"] = ""; diff --git a/classes/stack/cas/cassession.class.php b/classes/stack/cas/cassession.class.php index fb7886d8..12c52948 100644 --- a/classes/stack/cas/cassession.class.php +++ b/classes/stack/cas/cassession.class.php @@ -531,7 +531,7 @@ private function construct_maxima_command() { } // Special handling for the conditionally evaluated strings. - if (count($cs->get_conditions()) > 0) { + if (!empty($cs->get_conditions())) { $conditions = array(); foreach ($cs->get_conditions() as $cond) { // No need to evaluate again if it is already evaluated. diff --git a/classes/stack/cas/casstring.class.php b/classes/stack/cas/casstring.class.php index ca560f28..404e4254 100644 --- a/classes/stack/cas/casstring.class.php +++ b/classes/stack/cas/casstring.class.php @@ -555,7 +555,7 @@ public function __construct($rawstring, $conditions = null) { if (!($conditions === null || is_array($conditions))) { throw new stack_exception('stack_cas_casstring: conditions must be null or an array.'); } - if (count($conditions) != 0) { + if (!empty($conditions)) { $this->conditions = $conditions; } } diff --git a/classes/stack/cas/castext.class.php b/classes/stack/cas/castext.class.php index b77401f6..db3bec56 100644 --- a/classes/stack/cas/castext.class.php +++ b/classes/stack/cas/castext.class.php @@ -356,10 +356,10 @@ private function instantiate() { return false; } - // Deal with castext without any CAS variables. - if (null !== $this->session && count($this->session->get_session()) > 0) { - $this->session->instantiate(); - } + // Deal with castext without any CAS variables. + if (null !== $this->session && !empty($this->session->get_session())) { + $this->session->instantiate(); + } // Handle blocks. $requiresrerun = false; diff --git a/classes/stack/cas/connector.dbcache.class.php b/classes/stack/cas/connector.dbcache.class.php index 11b70d1a..c92d310f 100644 --- a/classes/stack/cas/connector.dbcache.class.php +++ b/classes/stack/cas/connector.dbcache.class.php @@ -119,7 +119,7 @@ protected function get_cached_result($command) // If there was more than one record in the cache (due to a race condition) // drop the duplicates. ////fim: #9 Use ILIAS DB instead of Moodle DB - if (sizeof($data) > 1) + if (!empty($data)) { unset($data[0]); foreach ($data as $record) diff --git a/classes/stack/input/checkbox/checkbox.class.php b/classes/stack/input/checkbox/checkbox.class.php index fc5dbd49..78cebe4d 100644 --- a/classes/stack/input/checkbox/checkbox.class.php +++ b/classes/stack/input/checkbox/checkbox.class.php @@ -154,11 +154,13 @@ public function response_to_contents($response) { } $contents = array(); - foreach ($this->ddlvalues as $key => $val) { - if (array_key_exists($this->name.'_'.$key, $response)) { - $contents[] = (int) $response[$this->name.'_'.$key]; - } - } + if(is_array($this->ddlvalues)){ + foreach ($this->ddlvalues as $key => $val) { + if (array_key_exists($this->name.'_'.$key, $response)) { + $contents[] = (int) $response[$this->name.'_'.$key]; + } + } + } return $contents; } diff --git a/classes/utils/class.assStackQuestionUtils.php b/classes/utils/class.assStackQuestionUtils.php index 1b45b8ed..45600359 100644 --- a/classes/utils/class.assStackQuestionUtils.php +++ b/classes/utils/class.assStackQuestionUtils.php @@ -146,10 +146,12 @@ public static function _getUserResponse($question_id, array $inputs, array $prev $current_response = array(); $user_response_from_db = array(); - if(sizeof($previous_response)){ + if (!empty($previous_response)) + { foreach ($previous_response["prt"] as $prt_name => $prt_info) { - if(sizeof($prt_info["response"])){ + if (!empty($prt_info["response"])) + { foreach ($prt_info["response"] as $input_name => $input_info) { $user_response_from_db[$input_name] = $input_info["value"]; @@ -179,7 +181,7 @@ public static function _getUserResponse($question_id, array $inputs, array $prev return $user_response; } - /** + /** * @param $user_response * @param $question_id * @param $inputs @@ -300,7 +302,7 @@ public static function _changeUserResponseStyle($user_response, $question_id, $i foreach ($inputs as $input_name => $input) { //If input is not matrix - if (is_subclass_of($input,"stack_dropdown_input")) + if (is_subclass_of($input, "stack_dropdown_input")) { $new_user_response_array['xqcas_input_' . $input_name . '_value'] = $input->maxima_to_response_array($user_response[$input_name]); } elseif (!is_a($input, 'stack_matrix_input')) @@ -641,4 +643,124 @@ public static function stack_output_castext($castext) return stack_maths::process_display_castext($castext); } + /** + * Returns the ID of each content styles available in the platform. + */ + public static function _getContentStylesAvailable() + { + global $DIC; + $db = $DIC->database(); + + $styles_id = array(); + $query = "SELECT id FROM style_data WHERE active = '1'"; + $result = $db->query($query); + while ($row = $db->fetchAssoc($result)) + { + $styles_id[] = $row["id"]; + } + + return $styles_id; + } + + /** + * Returns a text with a format from the content style + * @param $a_text + * @param $a_format + * @return string + */ + public static function _getFeedbackStyledText($a_text, $a_format) + { + //Get Styles assigned to Formats + $config_options = assStackQuestionConfig::_getStoredSettings("feedback"); + require_once "./Services/Style/Content/classes/class.ilObjStyleSheet.php"; + + //Return text depending Format + if (strlen($a_text)) + { + switch ($a_format) + { + case "feedback_default": + if ($config_options["feedback_default"] == "0") + { + return ''; + } else + { + $style_assigned = $config_options[$a_format]; + + return '
' . $a_text . '
'; + } + default: + //Use specific feedback style + $style_assigned = $config_options[$a_format]; + + return '
' . $a_text . '
'; + } + } else + { + return $a_text; + } + + } + + public static function _getActiveContentStyleId() + { + global $DIC; + $db = $DIC->database(); + + $styles_id = array(); + $query = "SELECT value FROM xqcas_configuration WHERE parameter_name = 'feedback_stylesheet_id'"; + $result = $db->query($query); + while ($row = $db->fetchAssoc($result)) + { + return $row["value"]; + } + } + + public static function _replaceFeedbackPlaceHolders($feedback){ + //Get Styles assigned to Formats + $config_options = assStackQuestionConfig::_getStoredSettings("feedback"); + + $text = $feedback; + //Search for right feedback + $style_assigned = $config_options["feedback_node_right"]; + $text = str_replace("[[feedback_node_right]]", '
',$text); + $text = str_replace("[[feedback_node_right_close]]", '
',$text); + + //Search for wrong feedback + $style_assigned = $config_options["feedback_node_wrong"]; + $text = str_replace("[[feedback_node_wrong]]", '
',$text); + $text = str_replace("[[feedback_node_wrong_close]]", '
',$text); + + //Search for wrong feedback + $style_assigned = $config_options["feedback_solution_hint"]; + $text = str_replace("[[feedback_solution_hint]]", '
',$text); + $text = str_replace("[[feedback_solution_hint_close]]", '
',$text); + + //Replace Extra info + $style_assigned = $config_options["feedback_extra_info"]; + $text = str_replace("[[feedback_extra_info]]", '
',$text); + $text = str_replace("[[feedback_extra_info_close]]", '
',$text); + + //Replace Extra info + $style_assigned = $config_options["feedback_plot_feedback"]; + $text = str_replace("[[feedback_plot_feedback]]", '
',$text); + $text = str_replace("[[feedback_plot_feedback_close]]", '
',$text); + + return $text; + } + + + public static function _isPhP72() + { + $php_version = phpversion(); + + $version = substr($php_version, 0, 3); + if ($version < 7.2) + { + return FALSE; + } else + { + return TRUE; + } + } } diff --git a/lang/ilias_de.lang b/lang/ilias_de.lang index 02b7c04f..429e726d 100644 --- a/lang/ilias_de.lang +++ b/lang/ilias_de.lang @@ -400,6 +400,25 @@ notes_best_solution_message#:#Notizen haben keine bestmögliche Lösung show_default_prts_settings#:#Vorgabewerte für Rückmeldebäume-Einstellungen default_prts_settings#:#Standard-Einstellungen für Rückmeldebäume und Knoten config_default_prts_message#:#Die Einstellungen für Rückmeldebäume wurden erfolgreich geändert. +prt_node_pos_feedback_class#:#Feedback-Style, wenn wahr +prt_node_pos_feedback_class_info#:#Wählen Sie den Feedback-Style, wenn der Answertest dieses Knotens wahr ist. +prt_node_neg_feedback_class#:#Feedback-Style, wenn falsch +prt_node_neg_feedback_class_info#:#Wählen Sie den Feedback-Style, wenn der Answertest dieses Knotens falsch ist. +feedback_styles_settings#:#Feedback-Style Einstellungen +feedback_styles_settings#:#Feedback-Style Einstellungen +feedback_node_right#:#Richtig +feedback_node_right_info#:#Feedback-Typ für richtige Antworten +feedback_node_wrong#:#Falsch +feedback_node_wrong_info#:#Feedback-Typ für falsche Antworten +feedback_solution_hint#:#Hinweis +feedback_solution_hint_info#:#Feedback-Style für Lösungshinweise +feedback_extra_info#:#Info +feedback_extra_info_info#:#Feedback-Style für zusätzliche Informationen +feedback_plot_feedback#:#Diagramm +feedback_plot_feedback_info#:#Für Diagramme benutzter Feedback-Style +config_feedback_styles_changed_message#:#Die Standardeinstellungen für Feedback-Style wurden erfolgreich geändert. +feedback_extra_1#:#Teilweise korrekt +feedback_extra_1_info#:#Feedback-Style für teilweise korrekte Antworten copy_node#:#Knoten kopieren paste_node#:#Knoten einfügen copy_prt#:# Rückmeldebaum kopieren @@ -431,4 +450,12 @@ servers_deactivated#:#Die Server wurden deaktiviert. no_server_selected#:#Bitte wählen Sie einen Server aus. confirm_delete_servers#:#Möchten Sie den/die folgenden Server löschen? server_deleted#:#Der Server wurde gelöscht. -servers_deleted#:#Die Server wurden gelöscht. \ No newline at end of file +servers_deleted#:#Die Server wurden gelöscht. +deletion_error_connected_node#:#You cannot delete this node as is connected to a PRT, please change the PRT structure to disconnect the node before delete it. +import_in_test_error#:#Import STACK questions from MoodleXML is not allowed in tests, please import it into a question pool before including it into a test. +feedback_stylesheet_id#:#Content-Style +feedback_stylesheet_id_info#:#Wählen Sie den Content-Style, der für das STACK-Feedback verwendet wird. Es können nur aktive Content-Style ausgewählt werden. Wenn kein Inhaltsstil ausgewählt ist, wird der Standard-Feedback-Style verwendet. Bitte beachten Sie, dass bei einer Änderung des Inhaltsstils alle Werte in diesem Formular auf Standard zurückgesetzt werden. +feedback_default#:#Allgemeiner Feedback-Style +feedback_default_info#:#Wählen Sie den Feedback-Style für Feedback-Nachrichten in STACK-Fragen. Er wird für den Abschnitt einer Feedback-Nachricht von STACK verwendet. Innerhalb dieses Abschnitts sind die Feedbacks der Knoten eines Rückmeldebaums eingebettet, die zusätzlich mit eigenen Styles versehen werden können. +nodes_feedback#:#Feedback von Knoten +config_prts_changed_message#:#Änderungen wurden übernommen \ No newline at end of file diff --git a/lang/ilias_en.lang b/lang/ilias_en.lang index 799cfd91..45eb8eef 100644 --- a/lang/ilias_en.lang +++ b/lang/ilias_en.lang @@ -400,26 +400,22 @@ notes_best_solution_message#:#Notes inputs have no best solution show_default_prts_settings#:#Default values for Potential response Trees and First nodes default_prts_settings#:#Default values for Potential response Trees config_default_prts_message#:#The default settings for PRT have been changed successfully. -prt_node_pos_feedback_class#:#Feedback Style if True -prt_node_pos_feedback_class_info#:#Choose the feedback style if this node's answertest is true, feedback style can be managed in plugin configuration. -prt_node_neg_feedback_class#:#Feedback Style if False -prt_node_neg_feedback_class_info#:#Choose the feedback style if this node's answertest is false, feedback style can be managed in plugin configuration. +prt_node_pos_feedback_class#:#Feedback Type if True +prt_node_pos_feedback_class_info#:#Choose the feedback style if this node's answertest is true +prt_node_neg_feedback_class#:#Feedback Type if False +prt_node_neg_feedback_class_info#:#Choose the feedback style if this node's answertest is false feedback_styles_settings#:#Feedback Styles Settings -feedback_node_right#:#Right Answer +feedback_node_right#:#Right feedback_node_right_info#:#Feedback style for right answers -feedback_node_wrong#:#Wrong Answer +feedback_node_wrong#:#Wrong feedback_node_wrong_info#:#Feedback style for wrong answers -feedback_solution_hint#:#Solution Hint +feedback_solution_hint#:#Hint feedback_solution_hint_info#:#Feedback style for solution hints -feedback_extra_info#:#Extra Information +feedback_extra_info#:#Info feedback_extra_info_info#:#Feedback style used for extra information feedback_plot_feedback#:#Plot feedback_plot_feedback_info#:#Feedback style used for plots config_feedback_styles_changed_message#:#The default settings for Feedback Styles have been changed successfully. -feedback_extra_1#:#Partially correct -feedback_extra_1_info#:#Feedback style for partially correct answers -options_stepwise_feedback#:#Stepwise Feedback -options_stepwise_feedback_info#:#Allow students to evaluate each PRT separately without reload the page copy_node#:#Copy Node paste_node#:#Paste Node copy_prt#:#Copy Potential Response Tree @@ -452,3 +448,11 @@ no_server_selected#:#Please select a server. confirm_delete_servers#:#Delete the following server(s)? server_deleted#:#The server is deleted. servers_deleted#:#The servers are deleted. +deletion_error_connected_node#:#You cannot delete this node as is connected to a PRT, please change the PRT structure to disconnect the node before delete it. +import_in_test_error#:#Import STACK questions from MoodleXML is not allowed in tests, please import it into a question pool before including it into a test. +feedback_stylesheet_id#:#Content Style +feedback_stylesheet_id_info#:#Select the content style used for STACK Feedback. Only active content styles can be selected. If no content style is chosen the default feedback style will be applied. Please notice, in case you change the content style, all values in this form will be set to default. +feedback_default#:#General Feedback Style +feedback_default_info#:#Select the feedback style for feedback messages in STACK questions. It is used for the section of a STACK feedback message. Within this section, the feedbacks of the nodes of a potential response tree are embedded, which can also be provided with their own styles. +nodes_feedback#:#Feedback from Nodes +config_prts_changed_message#:#Changes have been applied \ No newline at end of file diff --git a/plugin.php b/plugin.php index 26d350d5..2bd8993b 100644 --- a/plugin.php +++ b/plugin.php @@ -8,12 +8,13 @@ $id = "xqcas"; // code version; must be changed for all code changes -$version = "3.0.22"; + +$version = "3.1.5"; // ilias min and max version; must always reflect the versions that should // run with the plugin -$ilias_min_version = "5.3.0"; -$ilias_max_version = "5.3.999"; +$ilias_min_version = "5.4.0"; +$ilias_max_version = "5.4.999"; // optional, but useful: Add one or more responsible persons and a contact email $responsible = "Fred Neumann, Jesus Copado"; diff --git a/sql/dbupdate.php b/sql/dbupdate.php index 03c70412..f540d21d 100644 --- a/sql/dbupdate.php +++ b/sql/dbupdate.php @@ -737,4 +737,37 @@ $db->insert("xqcas_configuration", array('parameter_name' => array('text', "prt_neg_penalty"), 'value' => array('clob', '0'), 'group_name' => array('text', 'prts'))); $db->insert("xqcas_configuration", array('parameter_name' => array('text', "prt_neg_answernote"), 'value' => array('clob', 'prt1-0-F'), 'group_name' => array('text', 'prts'))); } -?> \ No newline at end of file +?> +<#36> + +<#37> +database(); +//Create feedback styles +if ($db->tableExists('xqcas_configuration')) +{ + //Feedback style 1 will be used as default, in case feedback_default is chosen, the value in true/false_feedback_format will be 1, and no specific style will be used, but platform style + $db->insert("xqcas_configuration", array('parameter_name' => array('text', "feedback_default"), 'value' => array('clob', ''), 'group_name' => array('text', 'feedback'))); + //Specific feedback formats. + $db->insert("xqcas_configuration", array('parameter_name' => array('text', "feedback_node_right"), 'value' => array('clob', ''), 'group_name' => array('text', 'feedback'))); + $db->insert("xqcas_configuration", array('parameter_name' => array('text', "feedback_node_wrong"), 'value' => array('clob', ''), 'group_name' => array('text', 'feedback'))); + $db->insert("xqcas_configuration", array('parameter_name' => array('text', "feedback_node_partially"), 'value' => array('clob', ''), 'group_name' => array('text', 'feedback'))); + $db->insert("xqcas_configuration", array('parameter_name' => array('text', "feedback_solution_hint"), 'value' => array('clob', ''), 'group_name' => array('text', 'feedback'))); + $db->insert("xqcas_configuration", array('parameter_name' => array('text', "feedback_extra_info"), 'value' => array('clob', ''), 'group_name' => array('text', 'feedback'))); + $db->insert("xqcas_configuration", array('parameter_name' => array('text', "feedback_plot_feedback"), 'value' => array('clob', ''), 'group_name' => array('text', 'feedback'))); +} +?> +<#38> +database(); +//Create feedback styles +if ($db->tableExists('xqcas_configuration')) +{ + //We have to store the id of the content style we want to use for stack feedback styles + $db->insert("xqcas_configuration", array('parameter_name' => array('text', "feedback_stylesheet_id"), 'value' => array('clob', ''), 'group_name' => array('text', 'feedback'))); +} +?>