From 5bbada53e3b786a2ecccd6b6c8ee5fc9d52730f2 Mon Sep 17 00:00:00 2001 From: Juan Leyva Date: Fri, 10 Mar 2017 10:51:32 +0100 Subject: [PATCH 1/2] MDL-58217 mod_feedback: API changes to allow generators We include a new function set_date at item level so we can add the data instead using the forms. --- mod/feedback/item/feedback_item_class.php | 13 +++++++++++++ mod/feedback/item/info/lib.php | 3 ++- mod/feedback/item/label/lib.php | 3 ++- mod/feedback/item/multichoice/lib.php | 3 ++- mod/feedback/item/multichoicerated/lib.php | 3 ++- mod/feedback/item/numeric/lib.php | 3 ++- mod/feedback/item/textarea/lib.php | 3 ++- mod/feedback/item/textfield/lib.php | 3 ++- 8 files changed, 27 insertions(+), 7 deletions(-) diff --git a/mod/feedback/item/feedback_item_class.php b/mod/feedback/item/feedback_item_class.php index 92eb10a4265..ec8294da471 100644 --- a/mod/feedback/item/feedback_item_class.php +++ b/mod/feedback/item/feedback_item_class.php @@ -55,12 +55,25 @@ abstract class feedback_item_base { * @return bool */ public function get_data() { + if ($this->item !== null) { + return true; + } if ($this->item = $this->item_form->get_data()) { return true; } return false; } + /** + * Set the item data (to be used by data generators). + * + * @param stdClass $itemdata the item data to set + * @since Moodle 3.3 + */ + public function set_data($itemdata) { + $this->item = $itemdata; + } + /** * Creates and returns an instance of the form for editing the item * diff --git a/mod/feedback/item/info/lib.php b/mod/feedback/item/info/lib.php index b96772cff27..3df76d23ff3 100644 --- a/mod/feedback/item/info/lib.php +++ b/mod/feedback/item/info/lib.php @@ -81,9 +81,10 @@ class feedback_item_info extends feedback_item_base { public function save_item() { global $DB; - if (!$item = $this->item_form->get_data()) { + if (!$this->get_data()) { return false; } + $item = $this->item; if (isset($item->clone_item) AND $item->clone_item) { $item->id = ''; //to clone this item diff --git a/mod/feedback/item/label/lib.php b/mod/feedback/item/label/lib.php index 6fa83bf5472..9fabd5126d0 100644 --- a/mod/feedback/item/label/lib.php +++ b/mod/feedback/item/label/lib.php @@ -89,9 +89,10 @@ class feedback_item_label extends feedback_item_base { public function save_item() { global $DB; - if (!$item = $this->item_form->get_data()) { + if (!$this->get_data()) { return false; } + $item = $this->item; if (isset($item->clone_item) AND $item->clone_item) { $item->id = ''; //to clone this item diff --git a/mod/feedback/item/multichoice/lib.php b/mod/feedback/item/multichoice/lib.php index d3b628bc16a..e9205ff5ac8 100644 --- a/mod/feedback/item/multichoice/lib.php +++ b/mod/feedback/item/multichoice/lib.php @@ -71,9 +71,10 @@ class feedback_item_multichoice extends feedback_item_base { public function save_item() { global $DB; - if (!$item = $this->item_form->get_data()) { + if (!$this->get_data()) { return false; } + $item = $this->item; if (isset($item->clone_item) AND $item->clone_item) { $item->id = ''; //to clone this item diff --git a/mod/feedback/item/multichoicerated/lib.php b/mod/feedback/item/multichoicerated/lib.php index 8be2faa97e8..8f80a5294a5 100644 --- a/mod/feedback/item/multichoicerated/lib.php +++ b/mod/feedback/item/multichoicerated/lib.php @@ -76,9 +76,10 @@ class feedback_item_multichoicerated extends feedback_item_base { public function save_item() { global $DB; - if (!$item = $this->item_form->get_data()) { + if (!$this->get_data()) { return false; } + $item = $this->item; if (isset($item->clone_item) AND $item->clone_item) { $item->id = ''; //to clone this item diff --git a/mod/feedback/item/numeric/lib.php b/mod/feedback/item/numeric/lib.php index add58cb88ae..2cddf274c94 100644 --- a/mod/feedback/item/numeric/lib.php +++ b/mod/feedback/item/numeric/lib.php @@ -76,9 +76,10 @@ class feedback_item_numeric extends feedback_item_base { public function save_item() { global $DB; - if (!$item = $this->item_form->get_data()) { + if (!$this->get_data()) { return false; } + $item = $this->item; if (isset($item->clone_item) AND $item->clone_item) { $item->id = ''; //to clone this item diff --git a/mod/feedback/item/textarea/lib.php b/mod/feedback/item/textarea/lib.php index 30172ca5f7a..6e9f5a901c9 100644 --- a/mod/feedback/item/textarea/lib.php +++ b/mod/feedback/item/textarea/lib.php @@ -76,9 +76,10 @@ class feedback_item_textarea extends feedback_item_base { public function save_item() { global $DB; - if (!$item = $this->item_form->get_data()) { + if (!$this->get_data()) { return false; } + $item = $this->item; if (isset($item->clone_item) AND $item->clone_item) { $item->id = ''; //to clone this item diff --git a/mod/feedback/item/textfield/lib.php b/mod/feedback/item/textfield/lib.php index cf0b3b0b1b2..c491f0b648f 100644 --- a/mod/feedback/item/textfield/lib.php +++ b/mod/feedback/item/textfield/lib.php @@ -73,9 +73,10 @@ class feedback_item_textfield extends feedback_item_base { public function save_item() { global $DB; - if (!$item = $this->item_form->get_data()) { + if (!$this->get_data()) { return false; } + $item = $this->item; if (isset($item->clone_item) AND $item->clone_item) { $item->id = ''; //to clone this item From 1abfa3a95e4204531c09f2c1a652738e2a09571a Mon Sep 17 00:00:00 2001 From: Juan Leyva Date: Fri, 10 Mar 2017 10:51:51 +0100 Subject: [PATCH 2/2] MDL-58217 mod_feedback: Add data generators for items --- mod/feedback/tests/generator/lib.php | 309 ++++++++++++++++++++++++++ mod/feedback/tests/generator_test.php | 173 ++++++++++++++ 2 files changed, 482 insertions(+) diff --git a/mod/feedback/tests/generator/lib.php b/mod/feedback/tests/generator/lib.php index f93472e52bd..402072290f5 100644 --- a/mod/feedback/tests/generator/lib.php +++ b/mod/feedback/tests/generator/lib.php @@ -83,5 +83,314 @@ class mod_feedback_generator extends testing_module_generator { return parent::create_instance($record, (array)$options); } + /** + * Create info question item. + * + * @param object $feedback feedback record + * @param array $record (optional) to override default values + * @return int + */ + public function create_item_info($feedback, $record = array()) { + global $DB, $CFG; + + require_once($CFG->dirroot.'/mod/feedback/lib.php'); + + $itemobj = feedback_get_item_class('info'); + $position = $DB->count_records('feedback_item', array('feedback' => $feedback->id)) + 1; + + $record = (array)$record + array( + 'id' => 0, + 'feedback' => $feedback->id, + 'template' => 0, + 'name' => 'Feedback question item ' . $position, + 'label' => 'Feedback label ' . $position, + 'presentation' => $itemobj::MODE_COURSE, + 'typ' => 'info', + 'hasvalue' => 0, + 'position' => $position, + 'required' => 0, + 'dependitem' => 0, + 'dependvalue' => '', + 'options' => '', + ); + + $itemobj->set_data((object) $record); + return $itemobj->save_item(); + } + + /** + * Create label question item. + * + * @param object $feedback feedback record + * @param array $record (optional) to override default values + * @return int + */ + public function create_item_label($feedback, $record = array()) { + global $DB, $CFG; + + require_once($CFG->dirroot.'/mod/feedback/lib.php'); + + $itemobj = feedback_get_item_class('label'); + $position = $DB->count_records('feedback_item', array('feedback' => $feedback->id)) + 1; + + $record = (array)$record + array( + 'id' => 0, + 'feedback' => $feedback->id, + 'template' => 0, + 'name' => 'label', + 'label' => '', + 'presentation' => '', + 'typ' => 'label', + 'hasvalue' => 0, + 'position' => $position, + 'required' => 0, + 'dependitem' => 0, + 'dependvalue' => '', + 'options' => '', + ); + + if (!isset($record['presentation_editor'])) { + $record['presentation_editor'] = array( + 'text' => "The label $position text goes here", + 'format' => FORMAT_HTML, + 'itemid' => 0 + ); + } + + $itemobj->set_data((object) $record); + return $itemobj->save_item(); + } + + /** + * Create multichoice question item. + * + * @param object $feedback feedback record + * @param array $record (optional) to override default values + * @return int + */ + public function create_item_multichoice($feedback, $record = array()) { + global $DB, $CFG; + + require_once($CFG->dirroot.'/mod/feedback/lib.php'); + + $itemobj = feedback_get_item_class('multichoice'); + $position = $DB->count_records('feedback_item', array('feedback' => $feedback->id)) + 1; + + $record = (array)$record + array( + 'id' => 0, + 'feedback' => $feedback->id, + 'template' => 0, + 'name' => 'Feedback question item ' . $position, + 'label' => 'Feedback label ' . $position, + 'presentation' => '', + 'typ' => 'multichoice', + 'hasvalue' => 0, + 'position' => $position, + 'required' => 0, + 'dependitem' => 0, + 'dependvalue' => '', + 'options' => '', + 'subtype' => 'r', + 'horizontal' => 0, + 'hidenoselect' => 1, + 'ignoreempty' => 0, + 'values' => "a\nb\nc\nd\ne" + ); + + $presentation = str_replace("\n", FEEDBACK_MULTICHOICE_LINE_SEP, trim($record['values'])); + + if ($record['horizontal'] == 1 AND $record['subtype'] != 'd') { + $presentation .= FEEDBACK_MULTICHOICE_ADJUST_SEP.'1'; + } + $record['presentation'] = $record['subtype'].FEEDBACK_MULTICHOICE_TYPE_SEP.$presentation; + + $itemobj->set_data((object) $record); + return $itemobj->save_item(); + } + + /** + * Create multichoicerated question item. + * + * @param object $feedback feedback record + * @param array $record (optional) to override default values + * @return int + */ + public function create_item_multichoicerated($feedback, $record = array()) { + global $DB, $CFG; + + require_once($CFG->dirroot.'/mod/feedback/lib.php'); + + $itemobj = feedback_get_item_class('multichoicerated'); + $position = $DB->count_records('feedback_item', array('feedback' => $feedback->id)) + 1; + + $record = (array)$record + array( + 'id' => 0, + 'feedback' => $feedback->id, + 'template' => 0, + 'name' => 'Feedback question item ' . $position, + 'label' => 'Feedback label ' . $position, + 'presentation' => '', + 'typ' => 'multichoicerated', + 'hasvalue' => 0, + 'position' => $position, + 'required' => 0, + 'dependitem' => 0, + 'dependvalue' => '', + 'options' => '', + 'subtype' => 'r', + 'horizontal' => 0, + 'hidenoselect' => 1, + 'ignoreempty' => 0, + 'values' => "0/a\n1/b\n2/c\n3/d\n4/e" + ); + + $itemobj = new feedback_item_multichoicerated(); + $presentation = $itemobj->prepare_presentation_values_save(trim($record['values']), + FEEDBACK_MULTICHOICERATED_VALUE_SEP2, FEEDBACK_MULTICHOICERATED_VALUE_SEP); + + if ($record['horizontal'] == 1 AND $record['subtype'] != 'd') { + $presentation .= FEEDBACK_MULTICHOICERATED_ADJUST_SEP.'1'; + } + $record['presentation'] = $record['subtype'].FEEDBACK_MULTICHOICERATED_TYPE_SEP.$presentation; + + $itemobj->set_data((object) $record); + return $itemobj->save_item(); + } + + /** + * Create numeric question item. + * + * @param object $feedback feedback record + * @param array $record (optional) to override default values + * @return int + */ + public function create_item_numeric($feedback, $record = array()) { + global $DB, $CFG; + + require_once($CFG->dirroot.'/mod/feedback/lib.php'); + + $itemobj = feedback_get_item_class('numeric'); + $position = $DB->count_records('feedback_item', array('feedback' => $feedback->id)) + 1; + + $record = (array)$record + array( + 'id' => 0, + 'feedback' => $feedback->id, + 'template' => 0, + 'name' => 'Feedback question item ' . $position, + 'label' => 'Feedback label ' . $position, + 'presentation' => '', + 'typ' => 'numeric', + 'hasvalue' => 0, + 'position' => $position, + 'required' => 0, + 'dependitem' => 0, + 'dependvalue' => '', + 'options' => '', + 'rangefrom' => '-', + 'rangeto' => '-', + ); + + if ($record['rangefrom'] === '-' OR $record['rangeto'] === '-') { + $record['presentation'] = $record['rangefrom'] . '|'. $record['rangeto']; + } else if ($record['rangefrom'] > $record['rangeto']) { + $record['presentation'] = $record['rangeto'] . '|'. $record['rangefrom']; + } else { + $record['presentation'] = $record['rangefrom'] . '|'. $record['rangeto']; + } + + $itemobj->set_data((object) $record); + return $itemobj->save_item(); + } + + /** + * Create textarea question item. + * + * @param object $feedback feedback record + * @param array $record (optional) to override default values + * @return int + */ + public function create_item_textarea($feedback, $record = array()) { + global $DB, $CFG; + + require_once($CFG->dirroot.'/mod/feedback/lib.php'); + + $itemobj = feedback_get_item_class('textarea'); + $position = $DB->count_records('feedback_item', array('feedback' => $feedback->id)) + 1; + + $record = (array)$record + array( + 'id' => 0, + 'feedback' => $feedback->id, + 'template' => 0, + 'name' => 'Feedback question item ' . $position, + 'label' => 'Feedback label ' . $position, + 'presentation' => '', + 'typ' => 'textarea', + 'hasvalue' => 0, + 'position' => $position, + 'required' => 0, + 'dependitem' => 0, + 'dependvalue' => '', + 'options' => '', + 'itemwidth' => '40', + 'itemheight' => '20', + ); + + $record['presentation'] = $record['itemwidth'] . '|'. $record['itemheight']; + + $itemobj->set_data((object) $record); + return $itemobj->save_item(); + } + + /** + * Create textfield question item. + * + * @param object $feedback feedback record + * @param array $record (optional) to override default values + * @return int + */ + public function create_item_textfield($feedback, $record = array()) { + global $DB, $CFG; + + require_once($CFG->dirroot.'/mod/feedback/lib.php'); + + $itemobj = feedback_get_item_class('textfield'); + $position = $DB->count_records('feedback_item', array('feedback' => $feedback->id)) + 1; + + $record = (array)$record + array( + 'id' => 0, + 'feedback' => $feedback->id, + 'template' => 0, + 'name' => 'Feedback question item ' . $position, + 'label' => 'Feedback label ' . $position, + 'presentation' => '', + 'typ' => 'textfield', + 'hasvalue' => 0, + 'position' => $position, + 'required' => 0, + 'dependitem' => 0, + 'dependvalue' => '', + 'options' => '', + 'itemsize' => '20', + 'itemmaxlength' => '30', + ); + + $record['presentation'] = $record['itemsize'] . '|'. $record['itemmaxlength']; + + $itemobj->set_data((object) $record); + return $itemobj->save_item(); + } + + /** + * Create pagebreak. + * + * @param object $feedback feedback record + * @return mixed false if there already is a pagebreak on last position or the id of the pagebreak-item + */ + public function create_item_pagebreak($feedback) { + global $CFG; + require_once($CFG->dirroot.'/mod/feedback/lib.php'); + + return feedback_create_pagebreak($feedback->id); + } } diff --git a/mod/feedback/tests/generator_test.php b/mod/feedback/tests/generator_test.php index 49ca8dfc716..bfb3a6c41d5 100644 --- a/mod/feedback/tests/generator_test.php +++ b/mod/feedback/tests/generator_test.php @@ -53,5 +53,178 @@ class mod_feedback_generator_testcase extends advanced_testcase { array('id' => $feedback->id))); } + public function test_create_item_info() { + global $DB; + $this->resetAfterTest(); + $this->setAdminUser(); + + $course = $this->getDataGenerator()->create_course(); + $feedback = $this->getDataGenerator()->create_module('feedback', array('course' => $course)); + $feedbackgenerator = $this->getDataGenerator()->get_plugin_generator('mod_feedback'); + + $item1 = $feedbackgenerator->create_item_info($feedback); + $item2 = $feedbackgenerator->create_item_info($feedback, array('name' => 'Custom name')); + $records = $DB->get_records('feedback_item', array('feedback' => $feedback->id), 'id'); + $this->assertCount(2, $records); + $this->assertEquals($item1->id, $records[$item1->id]->id); + $this->assertEquals($item2->id, $records[$item2->id]->id); + $this->assertEquals('Custom name', $records[$item2->id]->name); + $this->assertEquals('info', $records[$item1->id]->typ); + } + + public function test_create_item_label() { + global $DB; + $this->resetAfterTest(); + $this->setAdminUser(); + + $course = $this->getDataGenerator()->create_course(); + $feedback = $this->getDataGenerator()->create_module('feedback', array('course' => $course)); + $feedbackgenerator = $this->getDataGenerator()->get_plugin_generator('mod_feedback'); + + $item1 = $feedbackgenerator->create_item_label($feedback); + + $editor = array( + 'text' => "Custom editor", + 'format' => FORMAT_HTML, + 'itemid' => 0 + ); + $item2 = $feedbackgenerator->create_item_label($feedback, array('presentation_editor' => $editor)); + $records = $DB->get_records('feedback_item', array('feedback' => $feedback->id), 'id'); + $this->assertCount(2, $records); + $this->assertEquals($item1->id, $records[$item1->id]->id); + $this->assertEquals($item2->id, $records[$item2->id]->id); + $this->assertEquals($editor['text'], $records[$item2->id]->presentation); + $this->assertEquals('label', $records[$item1->id]->typ); + } + + public function test_create_item_multichoice() { + global $DB; + $this->resetAfterTest(); + $this->setAdminUser(); + + $course = $this->getDataGenerator()->create_course(); + $feedback = $this->getDataGenerator()->create_module('feedback', array('course' => $course)); + $feedbackgenerator = $this->getDataGenerator()->get_plugin_generator('mod_feedback'); + + $item1 = $feedbackgenerator->create_item_multichoice($feedback); + $item2 = $feedbackgenerator->create_item_multichoice($feedback, array('values' => "1\n2\n3\n4\n5", 'horizontal' => 1)); + $records = $DB->get_records('feedback_item', array('feedback' => $feedback->id), 'id'); + $this->assertCount(2, $records); + $this->assertEquals($item1->id, $records[$item1->id]->id); + $this->assertEquals($item2->id, $records[$item2->id]->id); + $this->assertEquals('r>>>>>a|b|c|d|e', $records[$item1->id]->presentation); + $this->assertEquals('r>>>>>1|2|3|4|5<<<<<1', $records[$item2->id]->presentation); + $this->assertEquals('multichoice', $records[$item1->id]->typ); + } + + public function test_create_item_multichoicerated() { + global $DB; + $this->resetAfterTest(); + $this->setAdminUser(); + + $course = $this->getDataGenerator()->create_course(); + $feedback = $this->getDataGenerator()->create_module('feedback', array('course' => $course)); + $feedbackgenerator = $this->getDataGenerator()->get_plugin_generator('mod_feedback'); + + $item1 = $feedbackgenerator->create_item_multichoicerated($feedback); + $item2 = $feedbackgenerator->create_item_multichoicerated($feedback, array( + 'values' => "0/1\n1/2\n2/3\n3/4\n4/5", 'horizontal' => 1)); + $records = $DB->get_records('feedback_item', array('feedback' => $feedback->id), 'id'); + $this->assertCount(2, $records); + $this->assertEquals($item1->id, $records[$item1->id]->id); + $this->assertEquals($item2->id, $records[$item2->id]->id); + $this->assertEquals('r>>>>>0####a|1####b|2####c|3####d|4####e', $records[$item1->id]->presentation); + $this->assertEquals('r>>>>>0####1|1####2|2####3|3####4|4####5<<<<<1', $records[$item2->id]->presentation); + $this->assertEquals('multichoicerated', $records[$item1->id]->typ); + } + + public function test_create_item_numeric() { + global $DB; + $this->resetAfterTest(); + $this->setAdminUser(); + + $course = $this->getDataGenerator()->create_course(); + $feedback = $this->getDataGenerator()->create_module('feedback', array('course' => $course)); + $feedbackgenerator = $this->getDataGenerator()->get_plugin_generator('mod_feedback'); + + $item1 = $feedbackgenerator->create_item_numeric($feedback); + $item2 = $feedbackgenerator->create_item_numeric($feedback, array('rangefrom' => '0', 'rangeto' => '10')); + $records = $DB->get_records('feedback_item', array('feedback' => $feedback->id), 'id'); + $this->assertCount(2, $records); + $this->assertEquals($item1->id, $records[$item1->id]->id); + $this->assertEquals($item2->id, $records[$item2->id]->id); + $this->assertEquals('-|-', $records[$item1->id]->presentation); + $this->assertEquals('0|10', $records[$item2->id]->presentation); + $this->assertEquals('numeric', $records[$item1->id]->typ); + } + + public function test_create_item_textarea() { + global $DB; + $this->resetAfterTest(); + $this->setAdminUser(); + + $course = $this->getDataGenerator()->create_course(); + $feedback = $this->getDataGenerator()->create_module('feedback', array('course' => $course)); + $feedbackgenerator = $this->getDataGenerator()->get_plugin_generator('mod_feedback'); + + $item1 = $feedbackgenerator->create_item_textarea($feedback); + $item2 = $feedbackgenerator->create_item_textarea($feedback, array('itemwidth' => '20', 'itemheight' => '10')); + $records = $DB->get_records('feedback_item', array('feedback' => $feedback->id), 'id'); + $this->assertCount(2, $records); + $this->assertEquals($item1->id, $records[$item1->id]->id); + $this->assertEquals($item2->id, $records[$item2->id]->id); + $this->assertEquals('40|20', $records[$item1->id]->presentation); + $this->assertEquals('20|10', $records[$item2->id]->presentation); + $this->assertEquals('textarea', $records[$item1->id]->typ); + } + + public function test_create_item_textfield() { + global $DB; + $this->resetAfterTest(); + $this->setAdminUser(); + + $course = $this->getDataGenerator()->create_course(); + $feedback = $this->getDataGenerator()->create_module('feedback', array('course' => $course)); + $feedbackgenerator = $this->getDataGenerator()->get_plugin_generator('mod_feedback'); + + $item1 = $feedbackgenerator->create_item_textfield($feedback); + $item2 = $feedbackgenerator->create_item_textfield($feedback, array('itemsize' => '20', 'itemmaxlength' => '10')); + $records = $DB->get_records('feedback_item', array('feedback' => $feedback->id), 'id'); + $this->assertCount(2, $records); + $this->assertEquals($item1->id, $records[$item1->id]->id); + $this->assertEquals($item2->id, $records[$item2->id]->id); + $this->assertEquals('20|30', $records[$item1->id]->presentation); + $this->assertEquals('20|10', $records[$item2->id]->presentation); + $this->assertEquals('textfield', $records[$item1->id]->typ); + } + + public function test_create_item_pagebreak() { + global $DB; + $this->resetAfterTest(); + $this->setAdminUser(); + + $course = $this->getDataGenerator()->create_course(); + $feedback = $this->getDataGenerator()->create_module('feedback', array('course' => $course)); + $feedbackgenerator = $this->getDataGenerator()->get_plugin_generator('mod_feedback'); + + // Try to create a page break in an empty feedback (no items). + $feedbackgenerator->create_item_pagebreak($feedback); + $records = $DB->get_records('feedback_item', array('feedback' => $feedback->id), 'id'); + $this->assertCount(0, $records); + + // Create at least one item before the pagebreak. + $feedbackgenerator->create_item_textfield($feedback); + + // Now, create one pagebreak. + $item1 = $feedbackgenerator->create_item_pagebreak($feedback); + $records = $DB->get_records('feedback_item', array('feedback' => $feedback->id), 'id'); + $this->assertCount(2, $records); + + // This pagebreak won't be created (there is already one in the last position). + $item2 = $feedbackgenerator->create_item_pagebreak($feedback); + $this->assertFalse($item2); + $records = $DB->get_records('feedback_item', array('feedback' => $feedback->id), 'id'); + $this->assertCount(2, $records); + } }