MDL-47494 ddmarker: NOBUG more work on code to validate coordinates entered when editing question

This commit is contained in:
Jamie Pratt
2011-11-14 15:39:44 +07:00
parent f881a720ef
commit 6f789d3dbd
3 changed files with 66 additions and 22 deletions
+14 -16
View File
@@ -92,22 +92,13 @@ class qtype_ddmarker_edit_form extends qtype_ddtoimage_edit_form_base {
return array();
}
protected function shapes() {
return preg_grep('!^qtype_ddmarker_shape_!', get_declared_classes());
return array('qtype_ddmarker_shape_circle',
'qtype_ddmarker_shape_rectangle',
'qtype_ddmarker_shape_polygon');
}
protected function drop_zone($mform, $imagerepeats) {
$dropzoneitem = array();
$grouparray = array();
$shapearray = array();
foreach ($this->shapes() as $shape) {
$shapearray[$shape::name()] = $shape::human_readable_name();
}
$shapearray = qtype_ddmarker_shape::shape_options();
$grouparray[] = $mform->createElement('select', 'shape',
get_string('marker', 'qtype_ddmarker'), $shapearray);
$grouparray[] = $mform->createElement('text', 'coords',
@@ -229,18 +220,25 @@ class qtype_ddmarker_edit_form extends qtype_ddtoimage_edit_form_base {
if ($choicepresent) {
//test coords here
if ($bgimagesize !== null) {
if (in_array($data['drops'][$i]['shape'], $this->shapes())) {
$shape = $data['drops'][$i]['shape'];
$coordsstring = $data['drops'][$i]['coords'];
$shapeobj = qtype_ddmarker_shape::create($shape, $coordsstring);
$interpretererror = $shapeobj->get_coords_interpreter_error();
if ($interpretererror) {
$errors["drops[{$i}]"] = $interpretererror;
} else if (!$shapeobj->inside_width_height($bgimagesize)) {
$errorcode = 'shapeoutsideboundsofbgimage';
$errors["drops[{$i}]"] =
get_string('formerror_'.$errorcode, 'qtype_ddmarker');
}
}
} else {
if (trim($data['drops'][$i]['coords']) !== '') {
$errors["drops[{$i}]"]
= get_string('formerror_noitemselected', 'qtype_ddmarker');
$errorcode = 'noitemselected';
$errors["drops[{$i}]"] = get_string('formerror_'.$errorcode, 'qtype_ddmarker');
}
}
}
for ($dragindex=0; $dragindex < $data['noitems']; $dragindex++) {
$label = $data['drags'][$dragindex]['label'];
@@ -43,13 +43,20 @@ $string['dropzoneheader'] = 'Drop zones';
$string['editingddmarker'] = 'Editing drag and drop markers';
$string['formerror_nobgimage'] = 'You need to select an image to use as the background for the drag and drop area.';
$string['formerror_noitemselected'] = 'You have specified a drop zone but not chosen a marker that must be dragged to the zone';
$string['formerror_nosemicolons'] = 'There are no semicolons in your coordinates string. Your coordinates for a {$a->shape} should be expressed as - {$a->coordsstring}.';
$string['formerror_notagsallowed'] = 'No html tags are allowed in the label for a marker';
$string['formerror_onlyusewholepositivenumbers'] = 'Please use only whole positive numbers to specify x,y coords and/or width and height of shapes. Your coordinates for a {$a->shape} should be expressed as - {$a->coordsstring}.';
$string['formerror_polygonmusthaveatleastthreepoints'] = 'For a polygon shape you need to specify at least 3 points. Your coordinates for a {$a->shape} should be expressed as - {$a->coordsstring}.';
$string['formerror_shapeoutsideboundsofbgimage'] = 'The shape you have defined goes out of the bounds of the background image';
$string['formerror_toomanysemicolons'] = 'There are too many semi colon separated parts to the coordinates you have specified. Your coordinates for a {$a->shape} should be expressed as - {$a->coordsstring}.';
$string['formerror_unrecognisedwidthheightpart'] = 'We do not recognise the width and height you have specified. Your coordinates for a {$a->shape} should be expressed as - {$a->coordsstring}.';
$string['formerror_unrecognisedxypart'] = 'We do not recognise the x,y coordinates you have specified. Your coordinates for a {$a->shape} should be expressed as - {$a->coordsstring}.';
$string['infinite'] = 'Infinite';
$string['marker'] = 'Marker';
$string['marker_n'] = 'Marker {no}';
$string['markers'] = 'Markers';
$string['nolabel'] = 'No label text';
$string['pleasedraganimagetoeachdropregion'] = 'Your answer is not complete, please drag an item to each drop region.';
$string['pleasedragatleastonemarker'] = 'Your answer is not complete, please drag at least one marker onto the image.';
$string['previewarea'] = 'Preview area -';
$string['previewareaheader'] = 'Preview';
$string['previewareamessage'] = 'Select a background image file, enter text labels for markers and define the drop zones on the background image to which they must be dragged.';
+44 -5
View File
@@ -23,6 +23,9 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
abstract class qtype_ddmarker_shape {
protected $error = false;
public function __construct($coordsstring) {
}
@@ -59,6 +62,17 @@ abstract class qtype_ddmarker_shape {
return true;
}
public function get_coords_interpreter_error() {
if ($this->error) {
$a = new stdClass();
$a->shape = self::human_readable_name();
$a->coordsstring = self::human_readable_coords_format();
return get_string('formerror_'.$this->error, 'qtype_ddmarker', $a);
} else {
return false;
}
}
/**
* @param array $xy $xy[0] is x, $xy[1] is y
* @return boolean is point inside shape
@@ -66,12 +80,37 @@ abstract class qtype_ddmarker_shape {
abstract public function is_point_in_shape($xy);
public static function name() {
return substr(get_called_class(), 21);
return substr(get_called_class(), strlen(self::$classnameprefix));
}
protected static $classnameprefix = 'qtype_ddmarker_shape_';
public static function human_readable_name() {
return get_string('shape_'.self::name(), 'qtype_ddmarker');
}
public static function human_readable_coords_format() {
return get_string('shape_'.self::name().'_coords', 'qtype_ddmarker');
}
public static function shape_options() {
$grepexpression = '!^'.preg_quote(self::$classnameprefix, '!').'!';
$shapes = preg_grep($grepexpression, get_declared_classes());
$shapearray = array();
foreach ($shapes as $shape) {
$shapearray[$shape::name()] = $shape::human_readable_name();
}
asort($shapearray);
return $shapearray;
}
public static function exists($shape) {
return class_exists((self::$classnameprefix).$shape);
}
public static function create($shape, $coordsstring) {
$classname = (self::$classnameprefix).$shape;
return new $classname($coordsstring);
}
}
class qtype_ddmarker_shape_rectangle extends qtype_ddmarker_shape {
protected $width;
@@ -81,14 +120,14 @@ class qtype_ddmarker_shape_rectangle extends qtype_ddmarker_shape {
public function __construct($coordsstring) {
$coordstring = preg_replace('!^\s*!', '', $coordsstring);
$coordstring = preg_replace('!\s*$!', '', $coordsstring);
$coordsstringparts = preg_split('!\s*!', $coordsstring);
$coordsstringparts = preg_split('!;!', $coordsstring);
if (count($coordsstringparts) > 2) {
$this->error = 'rectangletoomanyspaces';
$this->error = 'toomanysemicolons';
} else if (count($coordsstringparts) < 2) {
$this->error = 'rectanglenospaces';
$this->error = 'nosemicolons';
} else {
$xy = explode(',', $coordsstringparts[0]);
$widthheightparts = explode('x', $coordsstringparts[1]);
$widthheightparts = explode(',', $coordsstringparts[1]);
if (count($xy) !== 2) {
$this->error = 'unrecognisedxypart';
} else if (count($widthheightparts) !== 2) {