Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
4fcde5b
xml-edit - First pass at XML edit page
EJMFarrow Oct 28, 2025
7a36dab
xml-edit - Some tidying
EJMFarrow Oct 29, 2025
04529c7
xml-edit - Tidy
EJMFarrow Oct 30, 2025
12030de
xml-edit - Convert to Moodle form so we can use a sticky footer.
EJMFarrow Oct 30, 2025
7030d4b
xml-edit - Handle cancel and old Moodle. Catch import exceptions.
EJMFarrow Oct 30, 2025
f4ba1e3
xml-edit - Add behat test and importasversion dependency
EJMFarrow Oct 30, 2025
c7e63a7
xml-edit - Update CI
EJMFarrow Nov 4, 2025
6483760
Merge branch 'dev' of https://github.com/maths/moodle-qtype_stack int…
EJMFarrow Nov 6, 2025
c32688d
xml-edit - Make XML import consistent between Moodle and API.
EJMFarrow Nov 7, 2025
b14a2ff
xml-edit - Update unit tests
EJMFarrow Nov 10, 2025
2bcdaa1
xml-edit - Fix test.
EJMFarrow Nov 11, 2025
3e6b081
xml-edit - Gitsync compatability
EJMFarrow Nov 24, 2025
757d62e
xml-edit - Revert addChild change
EJMFarrow Nov 28, 2025
ce395d0
xml-edit - Update docs
EJMFarrow Nov 28, 2025
ceec79c
Merge branch 'dev' of https://github.com/maths/moodle-qtype_stack int…
EJMFarrow Dec 3, 2025
8ef2db0
xml-edit - Code tidy
EJMFarrow Dec 3, 2025
a8e0de1
xml-edit - Fix of the continuation fix after merge
EJMFarrow Dec 3, 2025
cb40349
xml-edit - Output validation messages on importasversion
EJMFarrow Dec 16, 2025
8a2c9b9
xml-edit - Add spaces to notice output for importasversion Moodle dis…
EJMFarrow Dec 17, 2025
5d7d602
xml-edit - Update CI. Fix deprecation.
EJMFarrow Dec 17, 2025
17c56a3
xml-edit - Fix formatting in api_stackquestionloader_test.php
EJMFarrow Dec 17, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/workflows/moodle-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:

services:
postgres:
image: postgres:15
image: postgres:16
env:
POSTGRES_USER: 'postgres'
POSTGRES_HOST_AUTH_METHOD: 'trust'
Expand Down Expand Up @@ -126,6 +126,7 @@ jobs:
moodle-plugin-ci add-plugin maths/moodle-qbehaviour_dfexplicitvaildate
moodle-plugin-ci add-plugin maths/moodle-qbehaviour_dfcbmexplicitvaildate
moodle-plugin-ci add-plugin maths/moodle-qbehaviour_adaptivemultipart
moodle-plugin-ci add-plugin maths/moodle-qbank_importasversion

moodle-plugin-ci install --plugin ./plugin --db-host=127.0.0.1

Expand Down Expand Up @@ -158,6 +159,7 @@ jobs:
moodle-plugin-ci add-plugin maths/moodle-qbehaviour_dfexplicitvaildate
moodle-plugin-ci add-plugin maths/moodle-qbehaviour_dfcbmexplicitvaildate
moodle-plugin-ci add-plugin maths/moodle-qbehaviour_adaptivemultipart
moodle-plugin-ci add-plugin maths/moodle-qbank_importasversion

moodle-plugin-ci install --plugin ./plugin --db-host=127.0.0.1

Expand Down
10 changes: 5 additions & 5 deletions api/controller/DiffController.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@

namespace api\controller;
defined('MOODLE_INTERNAL') || die();
require_once(__DIR__ . '/../dtos/StackRenderResponse.php');
require_once(__DIR__ . '/../dtos/StackDiffResponse.php');
require_once(__DIR__ . '/../util/StackQuestionLoader.php');

use api\dtos\StackRenderResponse;
use api\dtos\StackDiffResponse;
use api\util\StackQuestionLoader;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
Expand All @@ -39,11 +39,11 @@ public function __invoke(Request $request, Response $response, array $args): Res
// TO-DO: Validate.
$data = $request->getParsedBody();

$renderresponse = new StackRenderResponse();
$diffresponse = new StackDiffResponse();
$diff = StackQuestionLoader::detect_differences($data["questionDefinition"]);
$renderresponse->diff = $diff;
$diffresponse->diff = $diff;

$response->getBody()->write(json_encode($renderresponse));
$response->getBody()->write(json_encode($diffresponse));
return $response->withHeader('Content-Type', 'application/json');
}
}
File renamed without changes.
2 changes: 1 addition & 1 deletion api/questiondefaults.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ question:
penalty: '0.1'
hidden: '0'
idnumber: ''
stackversion: '2025042500'
stackversion: '2025102200'
questionvariables: 'ta1:1;'
specificfeedback: '<p>[[feedback:prt1]]</p>'
specificfeedbackformat: html
Expand Down
10 changes: 5 additions & 5 deletions api/util/StackQuestionLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ public static function loadxml($xml, $includetests = false) {
// Use (array) because isset($xmldata->question->defaultgrade) returns true if the element is empty and
// empty() returns true if element is 0. Casting to array returns [] and [0] which return false and true respectively.
$question->defaultmark = (array) $xmldata->question->defaultgrade ? (float) $xmldata->question->defaultgrade :
self::get_default('question', 'defaultgrade', 1.0);
self::get_default('question', 'defaultgrade', 1);
$question->penalty = (array) $xmldata->question->penalty ? (float) $xmldata->question->penalty :
self::get_default('question', 'penalty', 0.1);

Expand Down Expand Up @@ -164,7 +164,7 @@ public static function loadxml($xml, $includetests = false) {
self::get_default(
'question',
'prtcorrect',
get_string('defaultprtcorrectfeedback', 'qtype_stack', null)
get_config('qtype_stack', 'prtcorrect')
);
$question->prtcorrectformat = self::get_default('question', 'prtcorrectformat', 'html');
}
Expand All @@ -179,7 +179,7 @@ public static function loadxml($xml, $includetests = false) {
self::get_default(
'question',
'prtpartiallycorrect',
get_string('defaultprtpartiallycorrectfeedback', 'qtype_stack', null)
get_config('qtype_stack', 'prtpartiallycorrect')
);
$question->prtpartiallycorrectformat =
self::get_default('question', 'prtpartiallycorrectformat', 'html');
Expand All @@ -195,7 +195,7 @@ public static function loadxml($xml, $includetests = false) {
self::get_default(
'question',
'prtincorrect',
get_string('defaultprtincorrectfeedback', 'qtype_stack', null)
get_config('qtype_stack', 'prtincorrect')
);
$question->prtincorrectformat =
self::get_default('question', 'prtincorrectformat', 'html');
Expand Down Expand Up @@ -633,7 +633,7 @@ public static function yaml_to_xml($yamlstring) {
// Name is a special case. Has text tag but no format.
$name = (string) $xml->question->name ? (string) $xml->question->name : self::get_default('question', 'name', 'Default');
$xml->question->name = new SimpleXMLElement('<root></root>');
$xml->question->name->addChild('text', $name);
$xml->question->name->text = $name;
return $xml;
}

Expand Down
6 changes: 6 additions & 0 deletions doc/en/Developer/Development_history.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

For current and future plans, see [Development track](Development_track.md) and [Future plans](Future_plans.md).

## Version 4.12.0

- Validation of XML imports. XML files that fail validation will be marked as broken but still imported where possible.
- Editing of question XML within STACK from link in STACK dashboard. STACK now requires the importasversion plugin to make this possible.
- Much code tidying to comply with updated to Moodle Code Checker.

## Version 4.11.0

Released October 2025.
Expand Down
17 changes: 14 additions & 3 deletions doc/en/Installation/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ Please note

Instructions for installing a more recent version of Maxima on CentOS 6 are available on the [Moodle forum](https://moodle.org/mod/forum/discuss.php?d=270956) (Oct 2014).

## 3. Add some additional question behaviours
## 3. Add some additional question behaviours and importasversion

STACK requires these.

Expand All @@ -77,12 +77,17 @@ Alternatively, get the code using git by running the following command in the to
Alternatively, get the code using git by running the following command in the top level folder of your Moodle install:

git clone https://github.com/maths/moodle-qbehaviour_dfcbmexplicitvaildate.git question/behaviour/dfcbmexplicitvaildate
2. Obtain adaptivemutlipart behaviour code. You can [download the zip file](https://github.com/maths/moodle-qbehaviour_adaptivemultipart/zipball/master), unzip it, and place it in the directory `moodle/question/behaviour/adaptivemultipart`. (You will need to rename the directory `moodle-qbehaviour_adaptivemultipart -> adaptivemultipart`.)
3. Obtain adaptivemutlipart behaviour code. You can [download the zip file](https://github.com/maths/moodle-qbehaviour_adaptivemultipart/zipball/master), unzip it, and place it in the directory `moodle/question/behaviour/adaptivemultipart`. (You will need to rename the directory `moodle-qbehaviour_adaptivemultipart -> adaptivemultipart`.)

Alternatively, get the code using git by running the following command in the top level folder of your Moodle install:

git clone https://github.com/maths/moodle-qbehaviour_adaptivemultipart.git question/behaviour/adaptivemultipart
3. Login to Moodle as the admin user and click on Notifications in the Site Administration panel.
4. Obtain importasversion code. You can [download the zip file](https://github.com/maths/moodle-qbank_importasversion/archive/refs/heads/main.zip), unzip it, and place it in the directory `moodle/question/bank/importasversion`. (You will need to rename the directory `moodle-qbehaviour_importasversion -> importasversion`.)

Alternatively, get the code using git by running the following command in the top level folder of your Moodle install:

git clone https://github.com/maths/moodle-qbank_importasversion.git question/bank/importasversion
5. Login to Moodle as the admin user and click on Notifications in the Site Administration panel.

## 4. Add the STACK question type

Expand Down Expand Up @@ -164,6 +169,12 @@ If STACK is already installed, as described above, it can be updated via git, li
cd ..
cd adaptivemultipart/
git pull
cd ..
cd ..
cd bank/importasversion
git pull

If upgrading from an older version of STACK, you may need to install the importasversion plugin as instructed in installation step 3.

2. Then login as admin in your moodle and update the database.

Expand Down
11 changes: 9 additions & 2 deletions lang/en/qtype_stack.php
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,7 @@
$string['settingcaspreparse_false'] = 'Do not preparse (not recommended)';
$string['settingdefaultinputoptions'] = 'Default input options';
$string['settingdefaultinputoptions_desc'] = 'Used when creating a new question, or adding a new input to an existing question.';
$string['settingdefaultquestionoptions'] = 'Default input options';
$string['settingdefaultquestionoptions'] = 'Default question options';
$string['settingdefaultquestionoptions_desc'] = 'Used when creating a new question.';
$string['settingmathsdisplay'] = 'Maths filter';
$string['settingmathsdisplay_mathjax'] = 'MathJax';
Expand Down Expand Up @@ -622,6 +622,8 @@
$string['exportthisquestion_help'] = 'This will create a Moodle XML export file containing just this one question. One example of when this is useful if you think this question demonstrates a bug in STACK that you would like to report to the developers.';
$string['tidyquestion'] = '<i class="fa fa-sort-amount-asc"></i> Tidy inputs and PRTs';
$string['sendgeneralfeedback'] = '<i class="fa fa-file-text"></i> Send general feedback to the CAS';
$string['editxml'] = '<i class="fa fa-align-left"></i> Edit question XML';
$string['reloadsavedXML'] = '<i class="fa fa-rotate-left"></i> Reload saved version of question';
$string['seetodolist'] = '<i class="fa fa-exclamation-triangle"></i> Find <tt>[[todo]]</tt> blocks';
$string['seetodolist_desc'] = 'The purpose of this page is to find all questions containing <tt>[[todo]]</tt> blocks and to group them by any tags. Questions that have been marked as broken will also be found and displayed.';
$string['seetodolist_help'] = 'Clicking on the question name takes you to the dashboard. You can also preview the question.';
Expand All @@ -640,7 +642,7 @@
$string['splitsummary'] = 'Split summary';
$string['variants'] = 'Variants';

$string['importwillfail'] = 'Import will fail.';
$string['importwillfail'] = 'This question cannot be saved or imported in its current state.';
$string['noroots'] = 'The graph of this PRT has no roots. Does it have nodes?';
$string['structuralproblem'] = 'The PRT structure is malformed.';
$string['missingnextnode'] = 'The PRT structure is malformed. {$a->type} next node for PRT {$a->prt} node {$a->node} is invalid. It has been set to stop.';
Expand All @@ -666,6 +668,11 @@
$string['clearedthecache'] = 'CAS cached has been cleared.';
$string['clearingcachefiles'] = 'Clearing cached STACK plot files {$a->done}/{$a->total}';
$string['clearthecache'] = 'Clear the cache';
$string['editxmlintro'] = 'You can edit the XML of the question here and then save it as a new version of the question. Validation failures will result in a a warning being displayed and the saved question will be marked as broken (i.e. the <code>&lt;isbroken&gt;</code> tag will be set to 1). Serious issues with node layout may prevent the question from being saved. Missing question parts or invalid values are likely to cause an error. In most cases, you should see an error message and receive a warning that the question has not been saved. You can then edit your changes and try again. With great power comes great responsibility, however. If you are not careful with your XML, you will encounter issues and obscure error messages that you are protected from when using the normal question edit form. Please save frequently and/ or edit your question in another application to avoid losing work.';
$string['editxmltitle'] = 'Edit question XML';
$string['editxmlquestion'] = 'Question XML';
$string['editxmlbutton'] = 'Save as new version and continue editing';
$string['xmldisplayerror'] = ' There was a problem displaying the XML.';
$string['healthcheck'] = 'STACK healthcheck';
$string['healthcheck_desc'] = 'The <a href="{$a->link}">healthcheck script</a> helps you verify that all aspects of STACK are working properly.';
$string['healthcheckcache_db'] = 'CAS results are being cached in the database.';
Expand Down
6 changes: 6 additions & 0 deletions questiontestrun.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@
$exportparams['id'] = $question->id;

$questionbanklinkedit = new moodle_url('/question/type/stack/questioneditlatest.php', $editparams);
$questionxmllink = new moodle_url('/question/type/stack/questionxmledit.php', $editparams);
$questionbanklink = new moodle_url('/question/edit.php', $qbankparams);
$exportquestionlink = new moodle_url('/question/bank/exporttoxml/exportone.php', $exportparams);
$exportquestionlink->param('sesskey', sesskey());
Expand Down Expand Up @@ -156,6 +157,11 @@
stack_string('seetodolist'),
['class' => 'nav-link']
);
$links[] = html_writer::link(
$questionxmllink,
stack_string('editxml'),
['class' => 'nav-link']
);
echo html_writer::tag('nav', implode(' ', $links), ['class' => 'nav']);

flush();
Expand Down
Loading
Loading