Skip to content

Commit

Permalink
Parsons filter to extract final submission only
Browse files Browse the repository at this point in the history
  • Loading branch information
smmercuri committed Feb 6, 2025
1 parent d1e13e4 commit 131c031
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
require_once(__DIR__ . '/../../utils.class.php');

// phpcs:ignore moodle.Commenting.MissingDocblock.Class
class stack_ast_filter_909_parsons_decode_state_for_display implements stack_cas_astfilter {
class stack_ast_filter_908_parsons_decode_state_for_display implements stack_cas_astfilter {
// phpcs:ignore moodle.Commenting.MissingDocblock.Function
public function filter(MP_Node $ast, array &$errors, array &$answernotes, stack_cas_security $identifierrules): MP_Node {
$strings = function($node) use (&$answernotes, &$errors) {
Expand Down
47 changes: 47 additions & 0 deletions stack/cas/parsingrules/909_parsons_get_final_submission.filter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php
// This file is part of Stack - https://stack.maths.ed.ac.uk
//
// Stack is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Stack is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Stack. If not, see <http://www.gnu.org/licenses/>.

/**
* Add description here!
* @package qtype_stack
* @copyright 2024 University of Edinburgh.
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later.
*/

defined('MOODLE_INTERNAL') || die();
require_once(__DIR__ . '/filter.interface.php');
require_once(__DIR__ . '/../../utils.class.php');

// phpcs:ignore moodle.Commenting.MissingDocblock.Class
class stack_ast_filter_909_parsons_get_final_submission implements stack_cas_astfilter {
// phpcs:ignore moodle.Commenting.MissingDocblock.Function
public function filter(MP_Node $ast, array &$errors, array &$answernotes, stack_cas_security $identifierrules): MP_Node {
$strings = function($node) use (&$answernotes, &$errors) {
// We validate the node to check that it is a string that represents a Parson's state.
// This is not strictly required as it is prevented by `$node instanceof MP_String`, but it is an additional safety
// measure to ensure we do not dehash other strings.
if ($node instanceof MP_String && stack_parsons_input::validate_parsons_string($node->value)) {
$decoded = json_decode($node->value);
$node->value = json_encode(reset($decoded));
}

return true;
};

$ast->callbackRecurse($strings);
return $ast;
}
}
15 changes: 10 additions & 5 deletions stack/cas/parsingrules/parsingrule.factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@
require_once(__DIR__ . '/801_singleton_numeric.filter.php');
require_once(__DIR__ . '/802_singleton_units.filter.php');
require_once(__DIR__ . '/901_remove_comments.filter.php');
require_once(__DIR__ . '/909_parsons_decode_state_for_display.filter.php');
require_once(__DIR__ . '/908_parsons_decode_state_for_display.filter.php');
require_once(__DIR__ . '/909_parsons_get_final_submission.filter.php');
require_once(__DIR__ . '/910_inert_float_for_display.filter.php');
require_once(__DIR__ . '/912_inert_string_for_display.filter.php');
require_once(__DIR__ . '/990_no_fixing_spaces.filter.php');
Expand Down Expand Up @@ -190,8 +191,10 @@ private static function build_from_name(string $name): stack_cas_astfilter {
return new stack_ast_filter_802_singleton_units();
case '901_remove_comments':
return new stack_ast_filter_901_remove_comments();
case '909_parsons_decode_state_for_display' :
return new stack_ast_filter_909_parsons_decode_state_for_display();
case '908_parsons_decode_state_for_display' :
return new stack_ast_filter_908_parsons_decode_state_for_display();
case '909_parsons_get_final_submission':
return new stack_ast_filter_909_parsons_get_final_submission();
case '910_inert_float_for_display':
return new stack_ast_filter_910_inert_float_for_display();
case '912_inert_string_for_display':
Expand Down Expand Up @@ -251,8 +254,10 @@ public static function get_by_common_name(string $name): stack_cas_astfilter {
'601_castext', '602_castext_simplifier', '680_gcl_sconcat',
'610_castext_static_string_extractor',
'650_string_protect_slash',
'801_singleton_numeric', '802_singleton_units', '901_remove_comments',
'909_parsons_decode_state_for_display',
'801_singleton_numeric', '802_singleton_units',
'901_remove_comments',
'908_parsons_decode_state_for_display',
'909_parsons_get_final_submission',
'910_inert_float_for_display',
'912_inert_string_for_display',
'990_no_fixing_spaces', '991_no_fixing_stars',
Expand Down
4 changes: 4 additions & 0 deletions stack/input/inputbase.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -994,6 +994,10 @@ protected function validate_contents_filters($basesecurity) {
// Then ban the rest.
$filterstoapply[] = '505_no_evaluation_groups';

if (get_class($this) === 'stack_parsons_input') {
$filterstoapply[] = '909_parsons_get_final_submission';
}

// Remove scripts and other related things from string-values.
$filterstoapply[] = '997_string_security';

Expand Down
2 changes: 1 addition & 1 deletion stack/input/parsons/parsons.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ private static function answer_function_testcase($ta) {
* Filters to apply for display in validate_contents
* @var array
*/
protected $protectfilters = ['909_parsons_decode_state_for_display', '910_inert_float_for_display',
protected $protectfilters = ['908_parsons_decode_state_for_display', '910_inert_float_for_display',
'912_inert_string_for_display', ];

/**
Expand Down
2 changes: 1 addition & 1 deletion stack/maxima/contrib/prooflib.mac
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ proof_remove_nullproof(ex):= block(
* Take the JSON from STACK Parson's block and return a proof function.
*/
proof_parsons_interpret(st) := block([pf],
pf:first(first(stackjson_parse(st))),
pf:first(stackjson_parse(st)),
pf:apply(proof, first(first(stackmap_get(pf, "used"))))
);

Expand Down
2 changes: 1 addition & 1 deletion stack/maxima/proof.mac
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ parsons_encode(steps) := block(
* Take the hashed JSON from STACK Parson's block and return a proof function.
*/
parsons_decode(st) := block([pf],
pf:first(first(stackjson_parse(st))),
pf:first(stackjson_parse(st)),
pf:ev(apply(proof, unhash_keys_list(first(first(stackmap_get(pf, "used"))))),simp)
);

Expand Down
4 changes: 2 additions & 2 deletions stack/utils.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -1055,7 +1055,7 @@ public static function is_array_string($str) {
*/
public static function unhash_parsons_string($listofjsons) {
$decodedlist = json_decode($listofjsons);
if (!is_array($decoded)) {
if (!is_array($decodedlist)) {
return stack_string('invalid_json');;
}
foreach ($decodedlist as $key => $json) {
Expand Down Expand Up @@ -1098,7 +1098,7 @@ public static function unhash_parsons_string_maxima($listofjsons) {
*/
public static function hash_parsons_string($listofjsons) {
$decodedlist = json_decode($listofjsons);
if (!is_array($decoded)) {
if (!is_array($decodedlist)) {
return stack_string('invalid_json');;
}
foreach ($decodedlist as $key => $json) {
Expand Down

0 comments on commit 131c031

Please sign in to comment.