File tree 3 files changed +47
-1
lines changed
3 files changed +47
-1
lines changed Original file line number Diff line number Diff line change @@ -278,6 +278,7 @@ public function datasets_are_synchronised($category) {
278
278
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
279
279
*/
280
280
class qtype_calculated_variable_substituter {
281
+
281
282
/** @var array variable name => value */
282
283
protected $ values ;
283
284
@@ -466,7 +467,7 @@ protected function substitute_values_pretty($text) {
466
467
*/
467
468
public function replace_expressions_in_text ($ text , $ length = null , $ format = null ) {
468
469
$ vs = $ this ; // Can't use $this in a PHP closure.
469
- $ text = preg_replace_callback (' ~\{=([^{}]*(?:\{[^{}]+}[^{}]*)*)}~ ' ,
470
+ $ text = preg_replace_callback (qtype_calculated:: FORMULAS_IN_TEXT_REGEX ,
470
471
function ($ matches ) use ($ vs , $ format , $ length ) {
471
472
return $ vs ->format_float ($ vs ->calculate ($ matches [1 ]), $ length , $ format );
472
473
}, $ text );
Original file line number Diff line number Diff line change 37
37
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
38
38
*/
39
39
class qtype_calculated extends question_type {
40
+ /** Regular expression that finds the formulas in content. */
41
+ const FORMULAS_IN_TEXT_REGEX = '~\{=([^{}]*(?:\{[^{}]+}[^{}]*)*)\}~ ' ;
42
+
40
43
const MAX_DATASET_ITEMS = 100 ;
41
44
42
45
public $ wizardpagesnumber = 3 ;
@@ -1984,3 +1987,26 @@ function qtype_calculated_find_formula_errors($formula) {
1984
1987
return false ;
1985
1988
}
1986
1989
}
1990
+
1991
+ /**
1992
+ * Validate all the forumulas in a bit of text.
1993
+ * @param string $text the text in which to validate the formulas.
1994
+ * @return string|boolean false if there are no problems. Otherwise a string error message.
1995
+ */
1996
+ function qtype_calculated_find_formula_errors_in_text ($ text ) {
1997
+ preg_match_all (qtype_calculated::FORMULAS_IN_TEXT_REGEX , $ text , $ matches );
1998
+
1999
+ $ errors = array ();
2000
+ foreach ($ matches [1 ] as $ match ) {
2001
+ $ error = qtype_calculated_find_formula_errors ($ match );
2002
+ if ($ error ) {
2003
+ $ errors [] = $ error ;
2004
+ }
2005
+ }
2006
+
2007
+ if ($ errors ) {
2008
+ return implode (' ' , $ errors );
2009
+ }
2010
+
2011
+ return false ;
2012
+ }
Original file line number Diff line number Diff line change @@ -83,4 +83,23 @@ public function test_functions_with_wrong_num_args_caught() {
83
83
$ this ->assert_nonempty_string (qtype_calculated_find_formula_errors ('atan2(1.0, 1.0, 2.0) ' ));
84
84
$ this ->assert_nonempty_string (qtype_calculated_find_formula_errors ('max(1.0) ' ));
85
85
}
86
+
87
+ public function test_validation_of_formulas_in_text_ok () {
88
+ $ this ->assertFalse (qtype_calculated_find_formula_errors_in_text (
89
+ '<p>Look no equations.</p> ' ));
90
+ $ this ->assertFalse (qtype_calculated_find_formula_errors_in_text (
91
+ '<p>Simple variable: {x}.</p> ' ));
92
+ $ this ->assertFalse (qtype_calculated_find_formula_errors_in_text (
93
+ '<p>This is an equation: {=1+1}, as is this: {={x}+{y}}.</p> ' .
94
+ '<p>Here is a more complex one: {=sin(2*pi()*{theta})}.</p> ' ));
95
+ }
96
+
97
+ public function test_validation_of_formulas_in_text_bad_function () {
98
+ $ this ->assert_nonempty_string (qtype_calculated_find_formula_errors_in_text (
99
+ '<p>This is an equation: {=eval(1)}.</p> ' ));
100
+ $ this ->assert_nonempty_string (qtype_calculated_find_formula_errors_in_text (
101
+ '<p>Good: {=1+1}, bad: {=eval(1)}, good: {={x}+{y}}.</p> ' ));
102
+ $ this ->assert_nonempty_string (qtype_calculated_find_formula_errors_in_text (
103
+ '<p>Bad: {=eval(1)}, bad: {=system(1)}.</p> ' ));
104
+ }
86
105
}
You can’t perform that action at this time.
0 commit comments