</CUSTOM_CHECK>
</CUSTOM_CHECKS>
</MOODLE>
+ <MOODLE version="2.9" requires="2.2">
+ <UNICODE level="required">
+ <FEEDBACK>
+ <ON_ERROR message="unicoderequired" />
+ </FEEDBACK>
+ </UNICODE>
+ <DATABASE level="required">
+ <VENDOR name="mariadb" version="5.5.31" />
+ <VENDOR name="mysql" version="5.5.31" />
+ <VENDOR name="postgres" version="9.1" />
+ <VENDOR name="mssql" version="10.0" />
+ <VENDOR name="oracle" version="10.2" />
+ </DATABASE>
+ <PHP version="5.4.4" level="required">
+ </PHP>
+ <PCREUNICODE level="optional">
+ <FEEDBACK>
+ <ON_CHECK message="pcreunicodewarning" />
+ </FEEDBACK>
+ </PCREUNICODE>
+ <PHP_EXTENSIONS>
+ <PHP_EXTENSION name="iconv" level="required">
+ <FEEDBACK>
+ <ON_ERROR message="iconvrequired" />
+ </FEEDBACK>
+ </PHP_EXTENSION>
+ <PHP_EXTENSION name="mbstring" level="optional">
+ <FEEDBACK>
+ <ON_CHECK message="mbstringrecommended" />
+ </FEEDBACK>
+ </PHP_EXTENSION>
+ <PHP_EXTENSION name="curl" level="required">
+ <FEEDBACK>
+ <ON_ERROR message="curlrequired" />
+ </FEEDBACK>
+ </PHP_EXTENSION>
+ <PHP_EXTENSION name="openssl" level="optional">
+ <FEEDBACK>
+ <ON_CHECK message="opensslrecommended" />
+ </FEEDBACK>
+ </PHP_EXTENSION>
+ <PHP_EXTENSION name="tokenizer" level="optional">
+ <FEEDBACK>
+ <ON_CHECK message="tokenizerrecommended" />
+ </FEEDBACK>
+ </PHP_EXTENSION>
+ <PHP_EXTENSION name="xmlrpc" level="optional">
+ <FEEDBACK>
+ <ON_CHECK message="xmlrpcrecommended" />
+ </FEEDBACK>
+ </PHP_EXTENSION>
+ <PHP_EXTENSION name="soap" level="optional">
+ <FEEDBACK>
+ <ON_CHECK message="soaprecommended" />
+ </FEEDBACK>
+ </PHP_EXTENSION>
+ <PHP_EXTENSION name="ctype" level="required">
+ <FEEDBACK>
+ <ON_ERROR message="ctyperequired" />
+ </FEEDBACK>
+ </PHP_EXTENSION>
+ <PHP_EXTENSION name="zip" level="required">
+ <FEEDBACK>
+ <ON_ERROR message="ziprequired" />
+ </FEEDBACK>
+ </PHP_EXTENSION>
+ <PHP_EXTENSION name="zlib" level="required">
+ </PHP_EXTENSION>
+ <PHP_EXTENSION name="gd" level="required">
+ <FEEDBACK>
+ <ON_ERROR message="gdrequired" />
+ </FEEDBACK>
+ </PHP_EXTENSION>
+ <PHP_EXTENSION name="simplexml" level="required">
+ <FEEDBACK>
+ <ON_ERROR message="simplexmlrequired" />
+ </FEEDBACK>
+ </PHP_EXTENSION>
+ <PHP_EXTENSION name="spl" level="required">
+ <FEEDBACK>
+ <ON_ERROR message="splrequired" />
+ </FEEDBACK>
+ </PHP_EXTENSION>
+ <PHP_EXTENSION name="pcre" level="required">
+ </PHP_EXTENSION>
+ <PHP_EXTENSION name="dom" level="required">
+ </PHP_EXTENSION>
+ <PHP_EXTENSION name="xml" level="required">
+ </PHP_EXTENSION>
+ <PHP_EXTENSION name="intl" level="optional">
+ <FEEDBACK>
+ <ON_CHECK message="intlrecommended" />
+ </FEEDBACK>
+ </PHP_EXTENSION>
+ <PHP_EXTENSION name="json" level="required">
+ </PHP_EXTENSION>
+ <PHP_EXTENSION name="hash" level="required"/>
+ </PHP_EXTENSIONS>
+ <PHP_SETTINGS>
+ <PHP_SETTING name="memory_limit" value="96M" level="required">
+ <FEEDBACK>
+ <ON_ERROR message="settingmemorylimit" />
+ </FEEDBACK>
+ </PHP_SETTING>
+ <PHP_SETTING name="file_uploads" value="1" level="optional">
+ <FEEDBACK>
+ <ON_CHECK message="settingfileuploads" />
+ </FEEDBACK>
+ </PHP_SETTING>
+ <PHP_SETTING name="opcache.enable" value="1" level="optional">
+ <FEEDBACK>
+ <ON_CHECK message="opcacherecommended" />
+ </FEEDBACK>
+ </PHP_SETTING>
+ </PHP_SETTINGS>
+ <CUSTOM_CHECKS>
+ <CUSTOM_CHECK file="lib/upgradelib.php" function="check_database_storage_engine" level="required">
+ <FEEDBACK>
+ <ON_ERROR message="unsupporteddbstorageengine" />
+ </FEEDBACK>
+ </CUSTOM_CHECK>
+ <CUSTOM_CHECK file="question/engine/upgrade/upgradelib.php" function="quiz_attempts_upgraded" level="required">
+ <FEEDBACK>
+ <ON_ERROR message="quizattemptsupgradedmessage" />
+ </FEEDBACK>
+ </CUSTOM_CHECK>
+ </CUSTOM_CHECKS>
+ </MOODLE>
</COMPATIBILITY_MATRIX>
$string['unlockaccount'] = 'Unlock account';
$string['unsettheme'] = 'Unset theme';
$string['unsupported'] = 'Unsupported';
+$string['unsupporteddbstorageengine'] = 'The database storage engine being used is no longer supported.';
$string['unsuspenduser'] = 'Activate user account';
$string['updateaccounts'] = 'Update existing accounts';
$string['updatecomponent'] = 'Update component';
$string['number'] = 'Group/member count';
$string['numgroups'] = 'Number of groups';
$string['nummembers'] = 'Members per group';
+$string['mygroups'] = 'My groups';
+$string['othergroups'] = 'Other groups';
$string['overview'] = 'Overview';
$string['potentialmembers'] = 'Potential members: {$a}';
$string['potentialmembs'] = 'Potential members';
}
return true;
}
-
- /**
- * Returns the current db engine.
- *
- * MyISAM is NOT supported!
- *
- * @return string or null MySQL engine name
- */
- public function get_dbengine() {
- if ($this->external) {
- return null;
- }
-
- $engine = parent::get_dbengine();
- if ($engine === 'MyISAM') {
- debugging('MyISAM tables are not supported in MariaDB driver!');
- $engine = 'XtraDB';
- }
- return $engine;
- }
}
$context = context_course::instance($course->id);
$aag = has_capability('moodle/site:accessallgroups', $context);
+ $usergroups = array();
if ($groupmode == VISIBLEGROUPS or $aag) {
$allowedgroups = groups_get_all_groups($course->id, 0, $course->defaultgroupingid);
+ // Get user's own groups and put to the top.
+ $usergroups = groups_get_all_groups($course->id, $USER->id, $course->defaultgroupingid);
} else {
$allowedgroups = groups_get_all_groups($course->id, $USER->id, $course->defaultgroupingid);
}
$groupsmenu[0] = get_string('allparticipants');
}
- if ($allowedgroups) {
- foreach ($allowedgroups as $group) {
- $groupsmenu[$group->id] = format_string($group->name);
- }
- }
+ $groupsmenu += groups_sort_menu_options($allowedgroups, $usergroups);
if ($groupmode == VISIBLEGROUPS) {
$grouplabel = get_string('groupsvisible');
}
}
+/**
+ * Turn an array of groups into an array of menu options.
+ * @param array $groups of group objects.
+ * @return array groupid => formatted group name.
+ */
+function groups_list_to_menu($groups) {
+ $groupsmenu = array();
+ foreach ($groups as $group) {
+ $groupsmenu[$group->id] = format_string($group->name);
+ }
+ return $groupsmenu;
+}
+
+/**
+ * Takes user's allowed groups and own groups and formats for use in group selector menu
+ * If user has allowed groups + own groups will add to an optgroup
+ * Own groups are removed from allowed groups
+ * @param array $allowedgroups All groups user is allowed to see
+ * @param array $usergroups Groups user belongs to
+ * @return array
+ */
+function groups_sort_menu_options($allowedgroups, $usergroups) {
+ $useroptions = array();
+ if ($usergroups) {
+ $useroptions = groups_list_to_menu($usergroups);
+
+ // Remove user groups from other groups list.
+ foreach ($usergroups as $group) {
+ unset($allowedgroups[$group->id]);
+ }
+ }
+
+ $allowedoptions = array();
+ if ($allowedgroups) {
+ $allowedoptions = groups_list_to_menu($allowedgroups);
+ }
+
+ if ($useroptions && $allowedoptions) {
+ return array(
+ 1 => array(get_string('mygroups', 'group') => $useroptions),
+ 2 => array(get_string('othergroups', 'group') => $allowedoptions)
+ );
+ } else if ($useroptions) {
+ return $useroptions;
+ } else {
+ return $allowedoptions;
+ }
+}
+
/**
* Generates html to print menu selector for course level, listing all groups.
* Note: This api does not do any group mode check use groups_print_course_menu() instead if you want proper checks.
$allowedgroups = groups_get_all_groups($course->id, $USER->id, $course->defaultgroupingid);
}
- foreach ($allowedgroups as $group) {
- $groupsmenu[$group->id] = format_string($group->name);
- }
+ $groupsmenu += groups_list_to_menu($allowedgroups);
if ($update) {
// Init activegroup array if necessary.
$context = context_module::instance($cm->id);
$aag = has_capability('moodle/site:accessallgroups', $context);
+ $usergroups = array();
if ($groupmode == VISIBLEGROUPS or $aag) {
$allowedgroups = groups_get_all_groups($cm->course, 0, $cm->groupingid); // any group in grouping
+ // Get user's own groups and put to the top.
+ $usergroups = groups_get_all_groups($cm->course, $USER->id, $cm->groupingid);
} else {
$allowedgroups = groups_get_all_groups($cm->course, $USER->id, $cm->groupingid); // only assigned groups
}
$groupsmenu[0] = get_string('allparticipants');
}
- if ($allowedgroups) {
- foreach ($allowedgroups as $group) {
- $groupsmenu[$group->id] = format_string($group->name);
- }
- }
+ $groupsmenu += groups_sort_menu_options($allowedgroups, $usergroups);
if ($groupmode == VISIBLEGROUPS) {
$grouplabel = get_string('groupsvisible');
}
}
+ // Set the global $COURSE.
+ // TODO MDL-49434: setting current course/cm should be after the check $cm->uservisible .
+ if ($cm) {
+ $PAGE->set_cm($cm, $course);
+ $PAGE->set_pagelayout('incourse');
+ } else if (!empty($courseorid)) {
+ $PAGE->set_course($course);
+ }
+
// Check visibility of activity to current user; includes visible flag, conditional availability, etc.
if ($cm && !$cm->uservisible) {
if ($preventredirect) {
redirect($url, get_string('activityiscurrentlyhidden'));
}
- // Set the global $COURSE.
- if ($cm) {
- $PAGE->set_cm($cm, $course);
- $PAGE->set_pagelayout('incourse');
- } else if (!empty($courseorid)) {
- $PAGE->set_course($course);
- }
-
// Finally access granted, update lastaccess times.
user_accesstime_log($course->id);
}
Behat\Behat\Context\Step\When as When,
Behat\Behat\Context\Step\Then as Then,
Behat\Gherkin\Node\TableNode as TableNode,
+ Behat\Gherkin\Node\PyStringNode as PyStringNode,
Behat\Mink\Element\NodeElement as NodeElement,
Behat\Mink\Exception\ExpectationException as ExpectationException,
Behat\Mink\Exception\ElementNotFoundException as ElementNotFoundException;
$this->set_field_value($field, $value);
}
+ /**
+ * Sets the specified value to the field.
+ *
+ * @Given /^I set the field "(?P<field_string>(?:[^"]|\\")*)" to multiline$/
+ * @throws ElementNotFoundException Thrown by behat_base::find
+ * @param string $field
+ * @param PyStringNode $value
+ * @return void
+ */
+ public function i_set_the_field_to_multiline($field, PyStringNode $value) {
+ $this->set_field_value($field, (string)$value);
+ }
+
/**
* Sets the specified value to the field with xpath.
*
$this->assertCount(0, $usergroups1[0]);
$this->assertCount(0, $usergroups2[0]);
}
+
+ /**
+ * Create dummy groups array for use in menu tests
+ * @param int $number
+ * @return array
+ */
+ protected function make_group_list($number) {
+ $testgroups = array();
+ for ($a = 0; $a < $number; $a++) {
+ $grp = new stdClass();
+ $grp->id = 100 + $a;
+ $grp->name = 'test group ' . $grp->id;
+ $testgroups[$grp->id] = $grp;
+ }
+ return $testgroups;
+ }
+
+ public function test_groups_sort_menu_options_empty() {
+ $this->assertEquals(array(), groups_sort_menu_options(array(), array()));
+ }
+
+ public function test_groups_sort_menu_options_allowed_goups_only() {
+ $this->assertEquals(array(
+ 100 => 'test group 100',
+ 101 => 'test group 101',
+ ), groups_sort_menu_options($this->make_group_list(2), array()));
+ }
+
+ public function test_groups_sort_menu_options_user_goups_only() {
+ $this->assertEquals(array(
+ 100 => 'test group 100',
+ 101 => 'test group 101',
+ ), groups_sort_menu_options(array(), $this->make_group_list(2)));
+ }
+
+ public function test_groups_sort_menu_options_user_both() {
+ $this->assertEquals(array(
+ 1 => array(get_string('mygroups', 'group') => array(
+ 100 => 'test group 100',
+ 101 => 'test group 101',
+ )),
+ 2 => array(get_string('othergroups', 'group') => array(
+ 102 => 'test group 102',
+ 103 => 'test group 103',
+ )),
+ ), groups_sort_menu_options($this->make_group_list(4), $this->make_group_list(2)));
+ }
+
+ public function test_groups_sort_menu_options_user_both_many_groups() {
+ $this->assertEquals(array(
+ 1 => array(get_string('mygroups', 'group') => array(
+ 100 => 'test group 100',
+ 101 => 'test group 101',
+ )),
+ 2 => array (get_string('othergroups', 'group') => array(
+ 102 => 'test group 102',
+ 103 => 'test group 103',
+ 104 => 'test group 104',
+ 105 => 'test group 105',
+ 106 => 'test group 106',
+ 107 => 'test group 107',
+ 108 => 'test group 108',
+ 109 => 'test group 109',
+ 110 => 'test group 110',
+ 111 => 'test group 111',
+ 112 => 'test group 112',
+ )),
+ ), groups_sort_menu_options($this->make_group_list(13), $this->make_group_list(2)));
+ }
}
$rs->close();
$transaction->allow_commit();
}
+
+/**
+ * This function verifies that the database is not using an unsupported storage engine.
+ *
+ * @param environment_results $result object to update, if relevant
+ * @return environment_results|null updated results object, or null if the storage engine is supported
+ */
+function check_database_storage_engine(environment_results $result) {
+ global $DB;
+
+ // Check if MySQL is the DB family (this will also be the same for MariaDB).
+ if ($DB->get_dbfamily() == 'mysql') {
+ // Get the database engine we will either be using to install the tables, or what we are currently using.
+ $engine = $DB->get_dbengine();
+ // Check if MyISAM is the storage engine that will be used, if so, do not proceed and display an error.
+ if ($engine == 'MyISAM') {
+ $result->setInfo('unsupported_db_storage_engine');
+ $result->setStatus(false);
+ return $result;
+ }
+ }
+
+ return null;
+}
$fields = new backup_nested_element('fields');
$field = new backup_nested_element('field', array('id'), array(
- 'type', 'name', 'description', 'param1', 'param2',
+ 'type', 'name', 'description', 'required', 'param1', 'param2',
'param3', 'param4', 'param5', 'param6',
'param7', 'param8', 'param9', 'param10'));
<?xml version="1.0" encoding="UTF-8" ?>
-<XMLDB PATH="mod/data/db" VERSION="20120122" COMMENT="XMLDB file for Moodle mod/data"
+<XMLDB PATH="mod/data/db" VERSION="20150309" COMMENT="XMLDB file for Moodle mod/data"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
>
<FIELD NAME="type" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="name" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="description" TYPE="text" NOTNULL="true" SEQUENCE="false"/>
+ <FIELD NAME="required" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Required fields must have a value when inserted by a user"/>
<FIELD NAME="param1" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="param2" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="param3" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
<FIELD NAME="fieldid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="recordid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
- <FIELD NAME="content" TYPE="text" LENGTH="big" NOTNULL="false" SEQUENCE="false"/>
- <FIELD NAME="content1" TYPE="text" LENGTH="big" NOTNULL="false" SEQUENCE="false"/>
- <FIELD NAME="content2" TYPE="text" LENGTH="big" NOTNULL="false" SEQUENCE="false"/>
- <FIELD NAME="content3" TYPE="text" LENGTH="big" NOTNULL="false" SEQUENCE="false"/>
- <FIELD NAME="content4" TYPE="text" LENGTH="big" NOTNULL="false" SEQUENCE="false"/>
+ <FIELD NAME="content" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
+ <FIELD NAME="content1" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
+ <FIELD NAME="content2" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
+ <FIELD NAME="content3" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
+ <FIELD NAME="content4" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
</KEYS>
</TABLE>
</TABLES>
-</XMLDB>
\ No newline at end of file
+</XMLDB>
// Moodle v2.8.0 release upgrade line.
// Put any upgrade step following this.
- return true;
-}
+ if ($oldversion < 2015030900) {
+ // Define field required to be added to data_fields.
+ $table = new xmldb_table('data_fields');
+ $field = new xmldb_field('required', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0', 'description');
+
+ // Conditionally launch add field required.
+ if (!$dbman->field_exists($table, $field)) {
+ $dbman->add_field($table, $field);
+ }
+ upgrade_mod_savepoint(true, 2015030900, 'data');
+ }
+ return true;
+}
$cancel = optional_param('cancel', '', PARAM_RAW); // cancel an add
$mode ='addtemplate'; //define the mode for this page, only 1 mode available
+
+
$url = new moodle_url('/mod/data/edit.php');
if ($rid !== 0) {
+ $record = $DB->get_record('data_records', array(
+ 'id' => $rid,
+ 'dataid' => $d,
+ ), '*', MUST_EXIST);
$url->param('rid', $rid);
}
if ($cancel !== '') {
$PAGE->set_title($data->name);
$PAGE->set_heading($course->fullname);
-/// Process incoming data for adding/updating records
+// Process incoming data for adding/updating records.
+
+// Keep track of any notifications.
+$generalnotifications = array();
+$fieldnotifications = array();
+// Process the submitted form.
if ($datarecord = data_submitted() and confirm_sesskey()) {
+ if ($rid) {
+ // Updating an existing record.
- $ignorenames = array('MAX_FILE_SIZE','sesskey','d','rid','saveandview','cancel'); // strings to be ignored in input data
+ // Retrieve the format for the fields.
+ $fields = $DB->get_records('data_fields', array('dataid' => $datarecord->d));
- if ($rid) { /// Update some records
+ // Validate the form to ensure that enough data was submitted.
+ $processeddata = data_process_submission($data, $fields, $datarecord);
- /// All student edits are marked unapproved by default
- $record = $DB->get_record('data_records', array('id'=>$rid));
+ // Add the new notification data.
+ $generalnotifications = array_merge($generalnotifications, $processeddata->generalnotifications);
+ $fieldnotifications = array_merge($fieldnotifications, $processeddata->fieldnotifications);
- /// reset approved flag after student edit
- if (!has_capability('mod/data:approve', $context)) {
- $record->approved = 0;
- }
+ if ($processeddata->validated) {
+ // Enough data to update the record.
- $record->timemodified = time();
- $DB->update_record('data_records', $record);
+ // Obtain the record to be updated.
- /// Update all content
- $field = NULL;
- foreach ($datarecord as $name => $value) {
- if (!in_array($name, $ignorenames)) {
- $namearr = explode('_',$name); // Second one is the field id
- if (empty($field->field) || ($namearr[1] != $field->field->id)) { // Try to reuse classes
- $field = data_get_field_from_id($namearr[1], $data);
- }
- if ($field) {
- $field->update_content($rid, $value, $name);
- }
+ // Reset the approved flag after edit if the user does not have permission to approve their own entries.
+ if (!has_capability('mod/data:approve', $context)) {
+ $record->approved = 0;
}
- }
- // Trigger an event for updating this record.
- $event = \mod_data\event\record_updated::create(array(
- 'objectid' => $rid,
- 'context' => $context,
- 'courseid' => $course->id,
- 'other' => array(
- 'dataid' => $data->id
- )
- ));
- $event->add_record_snapshot('data', $data);
- $event->trigger();
-
- redirect($CFG->wwwroot.'/mod/data/view.php?d='.$data->id.'&rid='.$rid);
-
- } else { /// Add some new records
- ///Empty form checking - you can't submit an empty form!
-
- $emptyform = true; // assume the worst
-
- foreach ($datarecord as $name => $value) {
- if (!in_array($name, $ignorenames)) {
- $namearr = explode('_', $name); // Second one is the field id
- if (empty($field->field) || ($namearr[1] != $field->field->id)) { // Try to reuse classes
- $field = data_get_field_from_id($namearr[1], $data);
- }
- if ($field->notemptyfield($value, $name)) {
- $emptyform = false;
- break; // if anything has content, this form is not empty, so stop now!
- }
+ // Update the parent record.
+ $record->timemodified = time();
+ $DB->update_record('data_records', $record);
+
+ // Update all content.
+ foreach ($processeddata->fields as $fieldname => $field) {
+ $field->update_content($rid, $datarecord->$fieldname, $fieldname);
}
- }
- if ($emptyform){ //nothing gets written to database
- echo $OUTPUT->notification(get_string('emptyaddform','data'));
+ // Trigger an event for updating this record.
+ $event = \mod_data\event\record_updated::create(array(
+ 'objectid' => $rid,
+ 'context' => $context,
+ 'courseid' => $course->id,
+ 'other' => array(
+ 'dataid' => $data->id
+ )
+ ));
+ $event->add_record_snapshot('data', $data);
+ $event->trigger();
+
+ $viewurl = new moodle_url('/mod/data/view.php', array(
+ 'd' => $data->id,
+ 'rid' => $rid,
+ ));
+ redirect($viewurl);
}
- if (!$emptyform && $recordid = data_add_record($data, $currentgroup)) { //add instance to data_record
+ } else {
+ // No recordid was specified - creating a new entry.
- /// Insert a whole lot of empty records to make sure we have them
- $fields = $DB->get_records('data_fields', array('dataid'=>$data->id));
+ // Retrieve the format for the fields.
+ $fields = $DB->get_records('data_fields', array('dataid' => $datarecord->d));
+
+ // Validate the form to ensure that enough data was submitted.
+ $processeddata = data_process_submission($data, $fields, $datarecord);
+
+ // Add the new notification data.
+ $generalnotifications = array_merge($generalnotifications, $processeddata->generalnotifications);
+ $fieldnotifications = array_merge($fieldnotifications, $processeddata->fieldnotifications);
+
+ // Add instance to data_record.
+ if ($processeddata->validated && $recordid = data_add_record($data, $currentgroup)) {
+
+ // Insert a whole lot of empty records to make sure we have them.
+ $records = array();
foreach ($fields as $field) {
$content = new stdClass();
$content->recordid = $recordid;
$content->fieldid = $field->id;
- $DB->insert_record('data_content',$content);
+ $records[] = $content;
}
- /// For each field in the add form, add it to the data_content.
- foreach ($datarecord as $name => $value){
- if (!in_array($name, $ignorenames)) {
- $namearr = explode('_', $name); // Second one is the field id
- if (empty($field->field) || ($namearr[1] != $field->field->id)) { // Try to reuse classes
- $field = data_get_field_from_id($namearr[1], $data);
- }
- if ($field) {
- $field->update_content($recordid, $value, $name);
- }
- }
+ // Bulk insert the records now. Some records may have no data but all must exist.
+ $DB->insert_records('data_content', $records);
+
+ // Add all provided content.
+ foreach ($processeddata->fields as $fieldname => $field) {
+ $field->update_content($recordid, $datarecord->$fieldname, $fieldname);
}
+ // Trigger an event for updating this record.
+ $event = \mod_data\event\record_created::create(array(
+ 'objectid' => $rid,
+ 'context' => $context,
+ 'courseid' => $course->id,
+ 'other' => array(
+ 'dataid' => $data->id
+ )
+ ));
+ $event->add_record_snapshot('data', $data);
+ $event->trigger();
+
if (!empty($datarecord->saveandview)) {
- redirect($CFG->wwwroot.'/mod/data/view.php?d='.$data->id.'&rid='.$recordid);
+ $viewurl = new moodle_url('/mod/data/view.php', array(
+ 'd' => $data->id,
+ 'rid' => $recordid,
+ ));
+ redirect($viewurl);
}
}
}
-} // End of form processing
+}
+// End of form processing.
/// Print the page header
// To skip unnecessary calls to display_add_field().
if (strpos($data->addtemplate, "[[".$field->field->name."]]") !== false) {
+ // Replace the field tag.
$patterns[] = "[[".$field->field->name."]]";
- $replacements[] = $field->display_add_field($rid);
+ $errors = '';
+ if (!empty($fieldnotifications[$field->field->name])) {
+ foreach ($fieldnotifications[$field->field->name] as $notification) {
+ $errors .= $OUTPUT->notification($notification);
+ }
+ }
+ $replacements[] = $errors . $field->display_add_field($rid, $datarecord);
}
+
+ // Replace the field id tag.
$patterns[] = "[[".$field->field->name."#id]]";
$replacements[] = 'field_'.$field->field->id;
}
$newtext = '';
}
+foreach ($generalnotifications as $notification) {
+ echo $OUTPUT->notification($notification);
+}
echo $newtext;
echo '<div class="mdl-align"><input type="submit" name="saveandview" value="'.get_string('saveandview','data').'" />';
$field->field->name = $fieldinput->name;
$field->field->description = $fieldinput->description;
+ $field->field->required = !empty($fieldinput->required) ? 1 : 0;
for ($i=1; $i<=10; $i++) {
if (isset($fieldinput->{'param'.$i})) {
} else { //else print quiz style list of fields
$table = new html_table();
- $table->head = array(get_string('fieldname','data'), get_string('type','data'), get_string('fielddescription', 'data'), get_string('action','data'));
+ $table->head = array(
+ get_string('fieldname', 'data'),
+ get_string('type', 'data'),
+ get_string('required', 'data'),
+ get_string('fielddescription', 'data'),
+ get_string('action', 'data'),
+ );
$table->align = array('left','left','left', 'center');
$table->wrap = array(false,false,false,false);
$field = data_get_field($ff, $data);
- $table->data[] = array(
-
- '<a href="field.php?mode=display&d='.$data->id.
- '&fid='.$field->field->id.'&sesskey='.sesskey().'">'.$field->field->name.'</a>',
+ $baseurl = new moodle_url('/mod/data/field.php', array(
+ 'd' => $data->id,
+ 'fid' => $field->field->id,
+ 'sesskey' => sesskey(),
+ ));
- $field->image().' '.get_string($field->type, 'data'),
+ $displayurl = new moodle_url($baseurl, array(
+ 'mode' => 'display',
+ ));
- shorten_text($field->field->description, 30),
-
- '<a href="field.php?d='.$data->id.'&mode=display&fid='.$field->field->id.'&sesskey='.sesskey().'">'.
- '<img src="'.$OUTPUT->pix_url('t/edit') . '" class="iconsmall" alt="'.get_string('edit').'" title="'.get_string('edit').'" /></a>'.
- ' '.
- '<a href="field.php?d='.$data->id.'&mode=delete&fid='.$field->field->id.'&sesskey='.sesskey().'">'.
- '<img src="'.$OUTPUT->pix_url('t/delete') . '" class="iconsmall" alt="'.get_string('delete').'" title="'.get_string('delete').'" /></a>'
+ $deleteurl = new moodle_url($baseurl, array(
+ 'mode' => 'delete',
+ ));
+ $table->data[] = array(
+ html_writer::link($displayurl, $field->field->name),
+ $field->image() . ' ' . get_string($field->type, 'data'),
+ $field->field->required ? get_string('yes') : get_string('no'),
+ shorten_text($field->field->description, 30),
+ html_writer::link($displayurl, $OUTPUT->pix_icon('t/edit', get_string('edit'))) .
+ ' ' .
+ html_writer::link($deleteurl, $OUTPUT->pix_icon('t/delete', get_string('delete'))),
);
}
}
var $type = 'checkbox';
- function display_add_field($recordid=0) {
- global $CFG, $DB;
+ function display_add_field($recordid = 0, $formdata = null) {
+ global $CFG, $DB, $OUTPUT;
$content = array();
- if ($recordid) {
+ if ($formdata) {
+ $fieldname = 'field_' . $this->field->id;
+ $content = $formdata->$fieldname;
+ } else if ($recordid) {
$content = $DB->get_field('data_content', 'content', array('fieldid'=>$this->field->id, 'recordid'=>$recordid));
$content = explode('##', $content);
} else {
$content = array();
}
- $str = '<div title="'.s($this->field->description).'">';
- $str .= '<fieldset><legend><span class="accesshide">'.$this->field->name.'</span></legend>';
+ $str = '<div title="' . s($this->field->description) . '">';
+ $str .= '<fieldset><legend><span class="accesshide">'.$this->field->name;
+ if ($this->field->required) {
+ $str .= '$nbsp;' . get_string('requiredelement', 'form');
+ $str .= '</span></legend>';
+ $str .= '<div>';
+ $str .= html_writer::img($OUTPUT->pix_url('req'), get_string('requiredelement', 'form'),
+ array('class' => 'req', 'title' => get_string('requiredelement', 'form')));
+ $str .= '</div>';
+ } else {
+ $str .= '</span></legend>';
+ }
$i = 0;
foreach (explode("\n", $this->field->param1) as $checkbox) {
return implode('##', $vals);
}
-}
+ /**
+ * Check whether any boxes in the checkbox where checked.
+ *
+ * @param mixed $value The submitted values
+ * @param mixed $name
+ * @return bool
+ */
+ function notemptyfield($value, $name) {
+ $found = false;
+ foreach ($value as $checkboxitem) {
+ if (!empty($checkboxitem)) {
+ $found = true;
+ break;
+ }
+ }
+ return $found;
+ }
+}
<td class="c0"><label for="description"><?php echo get_string('fielddescription', 'data'); ?></label></td>
<td class="c1"><input class="fielddescription" type="text" name="description" id="description" value="<?php p($this->field->description); ?>" /></td>
</tr>
+ <tr>
+ <td class="c0"><label for="required"><?php echo get_string('requiredfield', 'data'); ?></label></td>
+ <td class="c1"><input class="requiredfield" type="checkbox" name="required" id="required" <?php p($this->field->required ? "checked=\"checked\"" : ""); ?>/></td>
+ </tr>
<tr>
<td class="c0" valign="top"><label for="param1"><?php echo get_string('fieldoptions', 'data'); ?></label></td>
<td class="c1"><textarea class="optionstextarea" name="param1" id="param1" cols="80" rows="10"><?php if($this->field->param1) {p($this->field->param1);} ?></textarea></td>
var $month = 0;
var $year = 0;
- function display_add_field($recordid=0) {
+ function display_add_field($recordid = 0, $formdata = null) {
global $DB, $OUTPUT;
- if ($recordid) {
+ if ($formdata) {
+ $fieldname = 'field_' . $this->field->id . '_day';
+ $day = $formdata->$fieldname;
+ $fieldname = 'field_' . $this->field->id . '_month';
+ $month = $formdata->$fieldname;
+ $fieldname = 'field_' . $this->field->id . '_year';
+ $year = $formdata->$fieldname;
+ $content = make_timestamp($year, $month, $day, 12, 0, 0, 0, false);
+ } else if ($recordid) {
$content = (int)$DB->get_field('data_content', 'content', array('fieldid'=>$this->field->id, 'recordid'=>$recordid));
} else {
$content = time();
}
-
-
class data_field_file extends data_field_base {
var $type = 'file';
- function display_add_field($recordid=0) {
+ function display_add_field($recordid = 0, $formdata = null) {
global $CFG, $DB, $OUTPUT, $PAGE, $USER;
$file = false;
$itemid = null;
// editing an existing database entry
- if ($recordid){
+ if ($formdata) {
+ $fieldname = 'field_' . $this->field->id . '_file';
+ $itemid = $formdata->$fieldname;
+ } else if ($recordid) {
if ($content = $DB->get_record('data_content', array('fieldid'=>$this->field->id, 'recordid'=>$recordid))) {
file_prepare_draft_area($itemid, $this->context->id, 'mod_data', 'content', $content->id);
$itemid = file_get_unused_draft_itemid();
}
- $html = '';
// database entry label
- $html .= '<div title="'.s($this->field->description).'">';
- $html .= '<fieldset><legend><span class="accesshide">'.$this->field->name.'</span></legend>';
+ $html = '<div title="' . s($this->field->description) . '">';
+ $html .= '<fieldset><legend><span class="accesshide">'.$this->field->name;
+
+ if ($this->field->required) {
+ $html .= ' ' . get_string('requiredelement', 'form') . '</span></legend>';
+ $image = html_writer::img($OUTPUT->pix_url('req'), get_string('requiredelement', 'form'),
+ array('class' => 'req', 'title' => get_string('requiredelement', 'form')));
+ $html .= html_writer::div($image);
+ } else {
+ $html .= '</span></legend>';
+ }
// itemid element
$html .= '<input type="hidden" name="field_'.$this->field->id.'_file" value="'.$itemid.'" />';
$output = $PAGE->get_renderer('core', 'files');
$html .= $output->render($fm);
-
$html .= '</fieldset>';
$html .= '</div>';
return true;
}
-}
-
+ /**
+ * Custom notempty function
+ *
+ * @param string $value
+ * @param string $name
+ * @return bool
+ */
+ function notemptyfield($value, $name) {
+ global $USER;
+
+ $names = explode('_', $name);
+ if ($names[2] == 'file') {
+ $usercontext = context_user::instance($USER->id);
+ $fs = get_file_storage();
+ $files = $fs->get_area_files($usercontext->id, 'user', 'draft', $value);
+ return count($files) >= 2;
+ }
+ return false;
+ }
+}
<td class="c0"><label for="description"><?php echo get_string('fielddescription', 'data'); ?></label></td>
<td class="c1"><input class="fielddescription" type="text" name="description" id="description" value="<?php p($this->field->description);?>" /></td>
</tr>
+ <tr>
+ <td class="c0"><label for="required"><?php echo get_string('requiredfield', 'data'); ?></label></td>
+ <td class="c1"><input class="requiredfield" type="checkbox" name="required" id="required" <?php p($this->field->required ? "checked=\"checked\"" : ""); ?>/></td>
+ </tr>
<tr>
<td class="c0"><label for="param3">
<?php echo get_string('maxsize', 'data'); ?></label></td>
);
// Other map sources listed at http://kvaleberg.com/extensions/mapsources/index.php?params=51_30.4167_N_0_7.65_W_region:earth
- function display_add_field($recordid=0) {
- global $CFG, $DB;
+ function display_add_field($recordid = 0, $formdata = null) {
+ global $CFG, $DB, $OUTPUT;
$lat = '';
$long = '';
- if ($recordid) {
+ if ($formdata) {
+ $fieldname = 'field_' . $this->field->id . '_0';
+ $lat = $formdata->$fieldname;
+ $fieldname = 'field_' . $this->field->id . '_1';
+ $long = $formdata->$fieldname;
+ } else if ($recordid) {
if ($content = $DB->get_record('data_content', array('fieldid'=>$this->field->id, 'recordid'=>$recordid))) {
$lat = $content->content;
$long = $content->content1;
$str = '<div title="'.s($this->field->description).'">';
$str .= '<fieldset><legend><span class="accesshide">'.$this->field->name.'</span></legend>';
$str .= '<table><tr><td align="right">';
- $str .= '<label for="field_'.$this->field->id.'_0">' . get_string('latitude', 'data') . '</label></td><td><input type="text" name="field_'.$this->field->id.'_0" id="field_'.$this->field->id.'_0" value="'.s($lat).'" size="10" />°N</td></tr>';
- $str .= '<tr><td align="right"><label for="field_'.$this->field->id.'_1">' . get_string('longitude', 'data') . '</label></td><td><input type="text" name="field_'.$this->field->id.'_1" id="field_'.$this->field->id.'_1" value="'.s($long).'" size="10" />°E</td></tr>';
+ $str .= '<label for="field_'.$this->field->id.'_0">' . get_string('latitude', 'data');
+ if ($this->field->required) {
+ $str .= html_writer::img($OUTPUT->pix_url('req'), get_string('requiredelement', 'form'),
+ array('class' => 'req', 'title' => get_string('requiredelement', 'form')));
+ }
+ $str .= '</label></td><td><input type="text" name="field_'.$this->field->id.'_0" id="field_'.$this->field->id.'_0" value="';
+ $str .= s($lat).'" size="10" />°N</td></tr>';
+ $str .= '<tr><td align="right"><label for="field_'.$this->field->id.'_1">' . get_string('longitude', 'data');
+ if ($this->field->required) {
+ $str .= html_writer::img($OUTPUT->pix_url('req'), get_string('requiredelement', 'form'),
+ array('class' => 'req', 'title' => get_string('requiredelement', 'form')));
+ }
+ $str .= '</label></td><td><input type="text" name="field_'.$this->field->id.'_1" id="field_'.$this->field->id.'_1" value="';
+ $str .= s($long).'" size="10" />°E</td>';
+ $str .= '</tr>';
$str .= '</table>';
$str .= '</fieldset>';
$str .= '</div>';
return sprintf('%01.4f', $record->content) . ' ' . sprintf('%01.4f', $record->content1);
}
-}
-
+ /**
+ * Check if a field from an add form is empty
+ *
+ * @param mixed $value
+ * @param mixed $name
+ * @return bool
+ */
+ function notemptyfield($value, $name) {
+ return isset($value) && !($value == '');
+ }
+}
<td class="c0"><label for="description"><?php echo get_string('fielddescription', 'data'); ?></label></td>
<td class="c1"><input class="fielddescription" type="text" name="description" id="description" value="<?php p ($this->field->description);?>" /></td>
</tr>
+ <tr>
+ <td class="c0"><label for="required"><?php echo get_string('requiredfield', 'data'); ?></label></td>
+ <td class="c1"><input class="requiredfield" type="checkbox" name="required" id="required" <?php p($this->field->required?"checked=\"checked\"":""); ?>/></td>
+ </tr>
<tr>
<td class="c0"><label for="param1"><?php echo get_string('latlonglinkservicesdisplayed', 'data'); ?></label></td>
<td class="c1">
var $type = 'menu';
- function display_add_field($recordid=0) {
+ function display_add_field($recordid = 0, $formdata = null) {
global $DB, $OUTPUT;
- if ($recordid){
+ if ($formdata) {
+ $fieldname = 'field_' . $this->field->id;
+ $content = $formdata->$fieldname;
+ } else if ($recordid) {
$content = $DB->get_field('data_content', 'content', array('fieldid'=>$this->field->id, 'recordid'=>$recordid));
$content = trim($content);
} else {
$content = '';
}
-
- $str = '<div title="'.s($this->field->description).'">';
+ $str = '<div title="' . s($this->field->description) . '">';
$options = array();
$rawoptions = explode("\n",$this->field->param1);
}
}
- $str .= html_writer::label(get_string('menuchoose', 'data'), 'field_'.$this->field->id, false, array('class' => 'accesshide'));
+ $str .= '<label for="' . 'field_' . $this->field->id . '">';
+ $str .= html_writer::span($this->field->name, 'accesshide');
+ if ($this->field->required) {
+ $image = html_writer::img($OUTPUT->pix_url('req'), get_string('requiredelement', 'form'),
+ array('class' => 'req', 'title' => get_string('requiredelement', 'form')));
+ $str .= html_writer::div($image);
+ }
+ $str .= '</label>';
$str .= html_writer::select($options, 'field_'.$this->field->id, $content, array(''=>get_string('menuchoose', 'data')), array('id'=>'field_'.$this->field->id));
$str .= '</div>';
}
}
-
-
<td class="c0"><label for="description"><?php echo get_string('fielddescription', 'data'); ?></label></td>
<td class="c1"><input class="fielddescription" type="text" name="description" id="description" value="<?php p($this->field->description);?>" /></td>
</tr>
+ <tr>
+ <td class="c0"><label for="required"><?php echo get_string('requiredfield', 'data'); ?></label></td>
+ <td class="c1"><input class="requiredfield" type="checkbox" name="required" id="required" <?php p($this->field->required?"checked=\"checked\"":""); ?>/></td>
+ </tr>
<tr>
<td class="c0" valign="top"><label for="param1"><?php echo get_string('fieldoptions', 'data'); ?></label></td>
<td class="c1"><textarea class="optionstextarea" name="param1" id="param1" cols="80" rows="10"><?php if($this->field->param1) {p($this->field->param1);} ?></textarea></td>
var $type = 'multimenu';
- function display_add_field($recordid=0) {
- global $DB;
+ function display_add_field($recordid = 0, $formdata = null) {
+ global $DB, $OUTPUT;
- if ($recordid){
+ if ($formdata) {
+ $fieldname = 'field_' . $this->field->id;
+ if (isset($formdata->$fieldname)) {
+ $content = $formdata->$fieldname;
+ } else {
+ $content = array();
+ }
+ } else if ($recordid) {
$content = $DB->get_field('data_content', 'content', array('fieldid'=>$this->field->id, 'recordid'=>$recordid));
$content = explode('##', $content);
} else {
$str = '<div title="'.s($this->field->description).'">';
$str .= '<input name="field_' . $this->field->id . '[xxx]" type="hidden" value="xxx"/>'; // hidden field - needed for empty selection
- $str .= '<label class="accesshide" for="field_' . $this->field->id . '">' . $this->field->name. '</label>';
+
+ $str .= '<label for="field_' . $this->field->id . '">';
+ $str .= html_writer::span($this->field->name, 'accesshide');
+ if ($this->field->required) {
+ $str .= '<div>';
+ $str .= html_writer::img($OUTPUT->pix_url('req'), get_string('requiredelement', 'form'),
+ array('class' => 'req', 'title' => get_string('requiredelement', 'form')));
+ $str .= '</div>';
+ }
+ $str .= '</label>';
$str .= '<select name="field_' . $this->field->id . '[]" id="field_' . $this->field->id . '" multiple="multiple">';
- foreach (explode("\n",$this->field->param1) as $option) {
+ foreach (explode("\n", $this->field->param1) as $option) {
$option = trim($option);
$str .= '<option value="' . s($option) . '"';
}
return false;
}
-}
+ /**
+ * Check if a field from an add form is empty
+ *
+ * @param mixed $value
+ * @param mixed $name
+ * @return bool
+ */
+ function notemptyfield($value, $name) {
+ unset($value['xxx']);
+ return !empty($value);
+ }
+}
<td class="c0"><label for="description"><?php echo get_string('fielddescription', 'data'); ?></label></td>
<td class="c1"><input class="fielddescription" type="text" name="description" id="description" value="<?php p($this->field->description); ?>" /></td>
</tr>
+ <tr>
+ <td class="c0"><label for="required"><?php echo get_string('requiredfield', 'data'); ?></label></td>
+ <td class="c1"><input class="requiredfield" type="checkbox" name="required" id="required" <?php p($this->field->required?"checked=\"checked\"":""); ?>/></td>
+ </tr>
<tr>
<td class="c0" valign="top"><label for="param1"><?php echo get_string('fieldoptions', 'data'); ?></label></td>
<td class="c1"><textarea class="optionstextarea" name="param1" id="param1" cols="80" rows="10"><?php if($this->field->param1) {p($this->field->param1);} ?></textarea></td>
<td class="c0"><label for="description"><?php echo get_string('fielddescription', 'data'); ?></label></td>
<td class="c1"><input class="fielddescription" type="text" name="description" id="description" value="<?php p($this->field->description);?>" /></td>
</tr>
+ <tr>
+ <td class="c0"><label for="required"><?php echo get_string('requiredfield', 'data'); ?></label></td>
+ <td class="c1"><input class="requiredfield" type="checkbox" name="required" id="required" <?php p($this->field->required?"checked=\"checked\"":""); ?>/></td>
+ </tr>
</table>
var $previewwidth = 50;
var $previewheight = 50;
- function display_add_field($recordid=0) {
+ function display_add_field($recordid = 0, $formdata = null) {
global $CFG, $DB, $OUTPUT, $USER, $PAGE;
$file = false;
$itemid = null;
$fs = get_file_storage();
- if ($recordid) {
+ if ($formdata) {
+ $fieldname = 'field_' . $this->field->id . '_file';
+ $itemid = $formdata->$fieldname;
+ $fieldname = 'field_' . $this->field->id . '_alttext';
+ if (isset($formdata->$fieldname)) {
+ $alttext = $formdata->$fieldname;
+ }
+ } else if ($recordid) {
if ($content = $DB->get_record('data_content', array('fieldid'=>$this->field->id, 'recordid'=>$recordid))) {
file_prepare_draft_area($itemid, $this->context->id, 'mod_data', 'content', $content->id);
if (!empty($content->content)) {
} else {
$itemid = file_get_unused_draft_itemid();
}
-
- $str = '<div title="'.s($this->field->description).'">';
- $str .= '<fieldset><legend><span class="accesshide">'.$this->field->name.'</span></legend>';
+ $str = '<div title="' . s($this->field->description) . '">';
+ $str .= '<fieldset><legend><span class="accesshide">'.$this->field->name;
+
+ if ($this->field->required) {
+ $str .= ' ' . get_string('requiredelement', 'form') . '</span></legend>';
+ $image = html_writer::img($OUTPUT->pix_url('req'), get_string('requiredelement', 'form'),
+ array('class' => 'req', 'title' => get_string('requiredelement', 'form')));
+ $str .= html_writer::div($image);
+ } else {
+ $str .= '</span></legend>';
+ }
$str .= '<noscript>';
if ($file) {
$src = file_encode_url($CFG->wwwroot.'/pluginfile.php/', $this->context->id.'/mod_data/content/'.$content->id.'/'.$file->get_filename());
function file_ok($path) {
return true;
}
-}
+ /**
+ * Custom notempty function
+ *
+ * @param string $value
+ * @param string $name
+ * @return bool
+ */
+ function notemptyfield($value, $name) {
+ global $USER;
+ $names = explode('_', $name);
+ if ($names[2] == 'file') {
+ $usercontext = context_user::instance($USER->id);
+ $fs = get_file_storage();
+ $files = $fs->get_area_files($usercontext->id, 'user', 'draft', $value);
+ return count($files) >= 2;
+ }
+ return false;
+ }
+}
<input class="fielddescription" type="text" name="description" id="description" value="<?php p($this->field->description);?>" />
</td>
</tr>
+ <tr>
+ <td class="c0"><label for="required"><?php echo get_string('requiredfield', 'data'); ?></label></td>
+ <td class="c1"><input class="requiredfield" type="checkbox" name="required" id="required" <?php p($this->field->required?"checked=\"checked\"":""); ?>/></td>
+ </tr>
<tr>
<td class="c0"><label for="param1">
<?php echo get_string('fieldwidthsingleview', 'data');?></label></td>
var $type = 'radiobutton';
- function display_add_field($recordid=0) {
- global $CFG, $DB;
+ function display_add_field($recordid = 0, $formdata = null) {
+ global $CFG, $DB, $OUTPUT;
- if ($recordid){
+ if ($formdata) {
+ $fieldname = 'field_' . $this->field->id;
+ if (isset($formdata->$fieldname)) {
+ $content = $formdata->$fieldname;
+ } else {
+ $content = '';
+ }
+ } else if ($recordid) {
$content = trim($DB->get_field('data_content', 'content', array('fieldid'=>$this->field->id, 'recordid'=>$recordid)));
} else {
$content = '';
}
- $str = '<div title="'.s($this->field->description).'">';
- $str .= '<fieldset><legend><span class="accesshide">'.$this->field->name.'</span></legend>';
+ $str = '<div title="' . s($this->field->description) . '">';
+ $str .= '<fieldset><legend><span class="accesshide">' . $this->field->name;
+
+ if ($this->field->required) {
+ $str .= ' ' . get_string('requiredelement', 'form') . '</span></legend>';
+ $image = html_writer::img($OUTPUT->pix_url('req'), get_string('requiredelement', 'form'),
+ array('class' => 'req', 'title' => get_string('requiredelement', 'form')));
+ $str .= html_writer::div($image);
+ } else {
+ $str .= '</span></legend>';
+ }
$i = 0;
- foreach (explode("\n",$this->field->param1) as $radio) {
+ $requiredstr = '';
+ $options = explode("\n", $this->field->param1);
+ foreach ($options as $radio) {
$radio = trim($radio);
if ($radio === '') {
continue; // skip empty lines
<td class="c0"><label for="description"><?php echo get_string('fielddescription', 'data'); ?></label></td>
<td class="c1"><input class="fielddescription" type="text" name="description" id="description" value="<?php p($this->field->description); ?>" /></td>
</tr>
+ <tr>
+ <td class="c0"><label for="required"><?php echo get_string('requiredfield', 'data'); ?></label></td>
+ <td class="c1"><input class="requiredfield" type="checkbox" name="required" id="required" <?php p($this->field->required?"checked=\"checked\"":""); ?>/></td>
+ </tr>
<tr>
<td class="c0" valign="top"><label for="param1"><?php echo get_string('fieldoptions', 'data'); ?></label></td>
<td class="c1"><textarea class="optionstextarea" name="param1" id="param1" cols="80" rows="10"><?php if($this->field->param1) {p($this->field->param1);} ?></textarea></td>
<td class="c0"><label for="description"><?php echo get_string('fielddescription', 'data'); ?></label></td>
<td class="c1"><input class="fielddescription" type="text" name="description" id="description" value="<?php p($this->field->description); ?>" /></td>
</tr>
+ <tr>
+ <td class="c0"><label for="required"><?php echo get_string('requiredfield', 'data'); ?></label></td>
+ <td class="c1"><input class="requiredfield" type="checkbox" name="required" id="required" <?php p($this->field->required?"checked=\"checked\"":""); ?>/></td>
+ </tr>
<tr>
<td class="c0"><label for="param1"><?php echo get_string('fieldallowautolink', 'data'); ?></label></td>
<td class="c1"><input type="checkbox" name="param1" id="param1" <?php if($this->field->param1) {echo 'checked="checked"';} ?> value="1" /></td>
return $options;
}
- function display_add_field($recordid=0) {
+ function display_add_field($recordid = 0, $formdata = null) {
global $CFG, $DB, $OUTPUT, $PAGE;
$text = '';
$format = 0;
-
- $str = '<div title="'.$this->field->description.'">';
+ $str = '<div title="' . s($this->field->description) . '">';
+ $str .= '<label for="field_' . $this->field->id . '">';
+ $str .= html_writer::span($this->field->name, "accesshide");
+ if ($this->field->required) {
+ $str .= html_writer::img($OUTPUT->pix_url('req'), get_string('requiredelement', 'form'),
+ array('class' => 'req', 'title' => get_string('requiredelement', 'form')));
+ }
+ $str .= '</label>';
editors_head_setup();
$options = $this->get_options();
$itemid = $this->field->id;
$field = 'field_'.$itemid;
- if ($recordid && $content = $DB->get_record('data_content', array('fieldid'=>$this->field->id, 'recordid'=>$recordid))){
+ if ($formdata) {
+ $fieldname = 'field_' . $this->field->id . '_content1';
+ if (isset($formdata->$fieldname)) {
+ $format = $formdata->$fieldname;
+ } else {
+ $format = file_get_unused_draft_itemid();
+ }
+ $fieldname = 'field_' . $this->field->id . '_itemid';
+ if (isset($formdata->$fieldname)) {
+ $draftitemid = $formdata->$fieldname;
+ } else {
+ $draftitemid = file_get_unused_draft_itemid();
+ }
+ $fieldname = 'field_' . $this->field->id;
+ if (isset($formdata->$fieldname)) {
+ $text = $formdata->$fieldname;
+ }
+ } else if ($recordid &&
+ $content = $DB->get_record('data_content', array('fieldid' => $this->field->id, 'recordid' => $recordid))) {
$format = $content->content1;
$text = clean_text($content->content, $format);
$text = file_prepare_draft_area($draftitemid, $this->context->id, 'mod_data', 'content', $content->id, $options, $text);
$str .= '<option value="'.s($key).'" '.$selected.'>'.$desc.'</option>';
}
$str .= '</select>';
- $str .= '</div>';
+ $str .= '</div>';
$str .= '</div>';
return $str;
}
function file_ok($relativepath) {
return true;
}
-}
+ /**
+ * Only look at the first item (second is format)
+ *
+ * @param string $value
+ * @param string $name
+ * @return bool
+ */
+ function notemptyfield($value, $name) {
+ $names = explode('_', $name);
+ // Clean first.
+ if (count($names) == 2) {
+ return !empty($value);
+ }
+ return false;
+ }
+}
value="<?php p($this->field->description); ?>" />
</td>
</tr>
+ <tr>
+ <td class="c0"><label for="required"><?php echo get_string('requiredfield', 'data'); ?></label></td>
+ <td class="c1"><input class="requiredfield" type="checkbox" name="required" id="required" <?php p($this->field->required?"checked=\"checked\"":""); ?>/></td>
+ </tr>
<tr>
<td class="c0"><label for="param2">
<?php echo get_string('fieldwidth', 'data'); ?></label></td>
class data_field_url extends data_field_base {
var $type = 'url';
- function display_add_field($recordid=0) {
+ function display_add_field($recordid = 0, $formdata = null) {
global $CFG, $DB, $OUTPUT, $PAGE;
require_once($CFG->dirroot. '/repository/lib.php'); // necessary for the constants used in args
$straddlink = get_string('choosealink', 'repository');
$url = '';
$text = '';
- if ($recordid) {
+ if ($formdata) {
+ $fieldname = 'field_' . $this->field->id . '_0';
+ $url = $formdata->$fieldname;
+ $fieldname = 'field_' . $this->field->id . '_1';
+ if (isset($formdata->$fieldname)) {
+ $text = $formdata->$fieldname;
+ }
+ } else if ($recordid) {
if ($content = $DB->get_record('data_content', array('fieldid'=>$this->field->id, 'recordid'=>$recordid))) {
$url = $content->content;
$text = $content->content1;
}
}
- $str = '<div title="'.s($this->field->description).'">';
+ $str = '<div title="' . s($this->field->description) . '">';
+
+ $label = '<label for="' . $fieldid . '"><span class="accesshide">' . $this->field->name . '</span>';
+ if ($this->field->required) {
+ $label .= html_writer::img($OUTPUT->pix_url('req'), get_string('requiredelement', 'form'),
+ array('class' => 'req', 'title' => get_string('requiredelement', 'form')));
+ }
+ $label .= '</label>';
+
if (!empty($this->field->param1) and empty($this->field->param2)) {
$str .= '<table><tr><td align="right">';
$str .= get_string('url','data').':</td><td>';
- $str .= '<label class="accesshide" for="' . $fieldid . '">'. $this->field->name .'</label>';
+ $str .= $label;
$str .= '<input type="text" name="field_'.$this->field->id.'_0" id="'.$fieldid.'" value="'.$url.'" size="60" />';
$str .= '<button id="filepicker-button-'.$options->client_id.'" style="display:none">'.$straddlink.'</button></td></tr>';
$str .= '<tr><td align="right">'.get_string('text','data').':</td><td><input type="text" name="field_'.$this->field->id.'_1" id="field_'.$this->field->id.'_1" value="'.s($text).'" size="60" /></td></tr>';
$str .= '</table>';
} else {
// Just the URL field
- $str .= '<label class="accesshide" for="' . $fieldid . '">'. $this->field->name .'</label>';
+ $str .= $label;
$str .= '<input type="text" name="field_'.$this->field->id.'_0" id="'.$fieldid.'" value="'.s($url).'" size="60" />';
if (count($options->repositories) > 0) {
$str .= '<button id="filepicker-button-'.$options->client_id.'" class="visibleifjs">'.$straddlink.'</button>';
$module = array('name'=>'data_urlpicker', 'fullpath'=>'/mod/data/data.js', 'requires'=>array('core_filepicker'));
$PAGE->requires->js_init_call('M.data_urlpicker.init', array($options), true, $module);
-
$str .= '</div>';
return $str;
}
}
}
-
-
<td class="c0"><label for="param1"><?php echo get_string('autolinkurl', 'data') ?></label></td>
<td class="c1"><input type="checkbox" name="param1" id="param1" <?php if($this->field->param1) {echo 'checked="checked"';} ?> value="1" /></td>
</tr>
+ <tr>
+ <td class="c0"><label for="required"><?php echo get_string('requiredfield', 'data'); ?></label></td>
+ <td class="c1"><input class="requiredfield" type="checkbox" name="required" id="required" <?php p($this->field->required?"checked=\"checked\"":""); ?>/></td>
+ </tr>
<tr>
<td class="c0"><label for="param3"><?php echo get_string('openlinkinnewwindow', 'datafield_url') ?></label></td>
<td class="c1"><input type="checkbox" name="param3" id="param3" <?php if($this->field->param3) {echo 'checked="checked"';} ?> value="1" /></td>
$string['entrysaved'] = 'Your entry has been saved';
$string['errormustbeteacher'] = 'You need to be a teacher to use this page!';
$string['errorpresetexists'] = 'There is already a preset with the selected name';
+$string['errormustsupplyvalue'] = 'You must supply a value here.';
$string['example'] = 'Database module example';
$string['excel'] = 'Excel';
$string['export'] = 'Export';
$string['recordssaved'] = 'entries saved';
$string['requireapproval'] = 'Approval required';
$string['requireapproval_help'] = 'If enabled, entries require approving by a teacher before they are viewable by everyone.';
+$string['required'] = 'Required';
$string['requiredentries'] = 'Entries required for completion';
$string['requiredentries_help'] = 'The number of entries a student is required to submit before the activity can be considered complete.';
$string['requiredentriestoview'] = 'Entries required before viewing';
$string['requiredentriestoview_help'] = 'The number of entries a student is required to submit before they can view entries from other students.
Note: If entries are required before viewing, the database auto-linking filter should be disabled. This is because the database auto-linking filter can\'t determine whether a user has submitted the required number of entries.';
+$string['requiredfield'] = 'Required field';
$string['resetsettings'] = 'Reset filters';
$string['resettemplate'] = 'Reset template';
$string['resizingimages'] = 'Resizing image thumbnails...';
$this->field->param3 = '';
$this->field->name = '';
$this->field->description = '';
+ $this->field->required = false;
return true;
}
$this->field->name = trim($data->name);
$this->field->description = trim($data->description);
+ $this->field->required = !empty($data->required) ? 1 : 0;
if (isset($data->param1)) {
$this->field->param1 = trim($data->param1);
* @param int $recordid
* @return string
*/
- function display_add_field($recordid=0){
- global $DB;
+ function display_add_field($recordid=0, $formdata=null) {
+ global $DB, $OUTPUT;
- if ($recordid){
+ if ($formdata) {
+ $fieldname = 'field_' . $this->field->id;
+ $content = $formdata->$fieldname;
+ } else if ($recordid) {
$content = $DB->get_field('data_content', 'content', array('fieldid'=>$this->field->id, 'recordid'=>$recordid));
} else {
$content = '';
$content='';
}
- $str = '<div title="'.s($this->field->description).'">';
- $str .= '<label class="accesshide" for="field_'.$this->field->id.'">'.$this->field->description.'</label>';
- $str .= '<input class="basefieldinput" type="text" name="field_'.$this->field->id.'" id="field_'.$this->field->id.'" value="'.s($content).'" />';
+ $str = '<div title="' . s($this->field->description) . '">';
+ $str .= '<label for="field_'.$this->field->id.'"><span class="accesshide">'.$this->field->name.'</span>';
+ if ($this->field->required) {
+ $str .= html_writer::img($OUTPUT->pix_url('req'), get_string('requiredelement', 'form'),
+ array('class' => 'req', 'title' => get_string('requiredelement', 'form')));
+ }
+ $str .= '</label><input class="basefieldinput" type="text" name="field_'.$this->field->id.'" id="field_'.$this->field->id;
+ $str .= '" value="'.s($content).'" />';
$str .= '</div>';
return $str;
foreach ($fields as $field) {
if ($form) { // Print forms instead of data
$fieldobj = data_get_field($field, $data);
- $token = $fieldobj->display_add_field($recordid);
+ $token = $fieldobj->display_add_field($recordid, null);
} else { // Just print the tag
$token = '[['.$field->name.']]';
}
}
return false;
}
+
+/**
+ * Check for required fields, and build a list of fields to be updated in a
+ * submission.
+ *
+ * @param $mod stdClass The current recordid - provided as an optimisation.
+ * @param $fields array The field data
+ * @param $datarecord stdClass The submitted data.
+ * @return stdClass containing:
+ * * string[] generalnotifications Notifications for the form as a whole.
+ * * string[] fieldnotifications Notifications for a specific field.
+ * * bool validated Whether the field was validated successfully.
+ * * data_field_base[] fields The field objects to be update.
+ */
+function data_process_submission(stdClass $mod, $fields, stdClass $datarecord) {
+ $result = new stdClass();
+
+ // Empty form checking - you can't submit an empty form.
+ $emptyform = true;
+ $requiredfieldsfilled = true;
+
+ // Store the notifications.
+ $result->generalnotifications = array();
+ $result->fieldnotifications = array();
+
+ // Store the instantiated classes as an optimisation when processing the result.
+ // This prevents the fields being re-initialised when updating.
+ $result->fields = array();
+
+ $submitteddata = array();
+ foreach ($datarecord as $fieldname => $fieldvalue) {
+ if (strpos($fieldname, '_')) {
+ $namearray = explode('_', $fieldname, 3);
+ $fieldid = $namearray[1];
+ if (!isset($submitteddata[$fieldid])) {
+ $submitteddata[$fieldid] = array();
+ }
+ if (count($namearray) === 2) {
+ $subfieldid = 0;
+ } else {
+ $subfieldid = $namearray[2];
+ }
+
+ $fielddata = new stdClass();
+ $fielddata->fieldname = $fieldname;
+ $fielddata->value = $fieldvalue;
+ $submitteddata[$fieldid][$subfieldid] = $fielddata;
+ }
+ }
+
+ // Check all form fields which have the required are filled.
+ foreach ($fields as $fieldrecord) {
+ // Check whether the field has any data.
+ $fieldhascontent = false;
+
+ $field = data_get_field($fieldrecord, $mod);
+ if (isset($submitteddata[$fieldrecord->id])) {
+ foreach ($submitteddata[$fieldrecord->id] as $fieldname => $value) {
+ if ($field->notemptyfield($value->value, $value->fieldname)) {
+ // The field has content and the form is not empty.
+ $fieldhascontent = true;
+ $emptyform = false;
+ }
+ }
+ }
+
+ // If the field is required, add a notification to that effect.
+ if ($field->field->required && !$fieldhascontent) {
+ if (!isset($result->fieldnotifications[$field->field->name])) {
+ $result->fieldnotifications[$field->field->name] = array();
+ }
+ $result->fieldnotifications[$field->field->name][] = get_string('errormustsupplyvalue', 'data');
+ $requiredfieldsfilled = false;
+ }
+
+ if ($fieldhascontent) {
+ // The field has content so it should be updatable.
+ foreach ($submitteddata[$fieldrecord->id] as $value) {
+ $result->fields[$value->fieldname] = $field;
+ }
+ }
+ }
+
+ if ($emptyform) {
+ // The form is empty.
+ $result->generalnotifications[] = get_string('emptyaddform', 'data');
+ }
+
+ $result->validated = $requiredfieldsfilled && !$emptyform;
+
+ return $result;
+}
.dir-rtl .mod-data-default-template .template-field {text-align:left;}
.dir-rtl .mod-data-default-template .template-token {text-align:right;}
.dir-rtl .mod-data-default-template searchcontrols {text-align:left;}
+
+#page-mod-data-edit .req {
+ cursor: help;
+}
When I log in as "student1"
And I follow "Course 1"
And I add an entry to "Test database name" database with:
- | Test field description | Student original entry |
+ | Test field name | Student original entry |
And I press "Save and view"
Then I should see "Student original entry"
And I follow "Edit"
And I set the following fields to these values:
- | Test field description | Student edited entry |
+ | Test field name | Student edited entry |
And I press "Save and view"
And I should see "Student edited entry"
And I add an entry to "Test database name" database with:
- | Test field description | Student second entry |
+ | Test field name | Student second entry |
And I press "Save and add another"
And I add an entry to "Test database name" database with:
- | Test field description | Student third entry |
+ | Test field name | Student third entry |
And I press "Save and view"
And I follow "View list"
And I should see "Student edited entry"
--- /dev/null
+@mod @mod_data
+Feature: Users can be required to specify certain fields when adding entries to database activities
+ In order to constrain user input
+ As a teacher
+ I need to specify certain fields as required when I add entries to databases
+
+ Background:
+ Given the following "users" exist:
+ | username | firstname | lastname | email |
+ | student1 | Student | 1 | student1@asd.com |
+ | teacher1 | Teacher | 1 | teacher1@asd.com |
+ And the following "courses" exist:
+ | fullname | shortname | category |
+ | Course 1 | C1 | 0 |
+ And the following "course enrolments" exist:
+ | user | course | role |
+ | teacher1 | C1 | editingteacher |
+ | student1 | C1 | student |
+ And the following "activities" exist:
+ | activity | name | intro | course | idnumber |
+ | data | Test database name | n | C1 | data1 |
+ And I log in as "teacher1"
+ And I follow "Course 1"
+ And I add a "Text input" field to "Test database name" database and I fill the form with:
+ | Field name | Base Text input |
+ | Required | yes |
+ | Field description | Base Text input |
+ And I add a "Checkbox" field to "Test database name" database and I fill the form with:
+ | Field name | Required Checkbox |
+ | Field description | Required Checkbox |
+ | Required | yes |
+ | Options | Required Checkbox Option 1 |
+ And I follow "Fields"
+ And I set the field "newtype" to "Checkbox"
+ And I click on "Go" "button" in the ".fieldadd" "css_element"
+ And I set the following fields to these values:
+ | Field name | Required Two-Option Checkbox |
+ | Field description | Required Two-Option Checkbox |
+ | Required | yes |
+ And I set the field "Options" to multiline
+ """
+ RTOC Option 1
+ RTOC Option 2
+ """
+ And I press "Add"
+ And I add a "Latlong" field to "Test database name" database and I fill the form with:
+ | Field name | Required Latlong |
+ | Field description | Required Latlong |
+ | Required | yes |
+ And I add a "Menu" field to "Test database name" database and I fill the form with:
+ | Field name | Required Menu |
+ | Field description | Required Menu |
+ | Required | yes |
+ | Options | Option 1 |
+ And I add a "Number" field to "Test database name" database and I fill the form with:
+ | Field name | Required Number |
+ | Field description | Required Number |
+ | Required | yes |
+ And I add a "Radio button" field to "Test database name" database and I fill the form with:
+ | Field name | Required Radio |
+ | Field description | Required Radio |
+ | Required | yes |
+ | Options | Required Radio Option 1 |
+ And I add a "Text input" field to "Test database name" database and I fill the form with:
+ | Field name | Required Text input |
+ | Field description | Required Text input |
+ | Required | yes |
+ And I add a "Text area" field to "Test database name" database and I fill the form with:
+ | Field name | Required Text area |
+ | Field description | Required Text area |
+ | Required | yes |
+ And I add a "URL" field to "Test database name" database and I fill the form with:
+ | Field name | Required URL |
+ | Field description | Required URL |
+ | Required | yes |
+ And I add a "Multimenu" field to "Test database name" database and I fill the form with:
+ | Field name | Required Multimenu |
+ | Field description | Required Multimenu |
+ | Required | yes |
+ | Options | Option 1 |
+ And I follow "Fields"
+ And I set the field "newtype" to "Multimenu"
+ And I click on "Go" "button" in the ".fieldadd" "css_element"
+ And I set the following fields to these values:
+ | Field name | Required Two-Option Multimenu |
+ | Field description | Required Two-Option Multimenu |
+ | Required | yes |
+ And I set the field "Options" to multiline
+ """
+ Option 1
+ Option 2
+ """
+ And I press "Add"
+ And I add a "Checkbox" field to "Test database name" database and I fill the form with:
+ | Field name | Not required Checkbox |
+ | Field description | Not required Checkbox |
+ | Options | Not required Checkbox Option 1 |
+ And I add a "Latlong" field to "Test database name" database and I fill the form with:
+ | Field name | Not required Latlong |
+ | Field description | Not required Latlong |
+ And I add a "Menu" field to "Test database name" database and I fill the form with:
+ | Field name | Not required Menu |
+ | Field description | Not required Menu |
+ | Options | Option 1 |
+ And I add a "Number" field to "Test database name" database and I fill the form with:
+ | Field name | Not required Number |
+ | Field description | Not required Number |
+ And I add a "Radio button" field to "Test database name" database and I fill the form with:
+ | Field name | Not required Radio |
+ | Field description | Not required Radio |
+ | Options | Not required Radio Option 1 |
+ And I add a "Text input" field to "Test database name" database and I fill the form with:
+ | Field name | Not required Text input |
+ | Field description | Not required Text input |
+ And I add a "Text area" field to "Test database name" database and I fill the form with:
+ | Field name | Not required Text area |
+ | Field description | Not required Text area |
+ And I add a "URL" field to "Test database name" database and I fill the form with:
+ | Field name | Not required URL |
+ | Field description | Not required URL |
+ And I add a "Multimenu" field to "Test database name" database and I fill the form with:
+ | Field name | Not required Multimenu |
+ | Field description | Not required Multimenu |
+ | Options | Option 1 |
+ And I follow "Templates"
+ And I log out
+
+ Scenario: Students receive errors for empty required fields but not for optional fields
+ When I log in as "student1"
+ And I follow "Course 1"
+ And I add an entry to "Test database name" database with:
+ | Base Text input | Some input to allow us to submit the otherwise empty form |
+ And I press "Save and view"
+ Then ".alert.alert-error" "css_element" should exist in the "Required Checkbox" "table_row"
+ And ".alert.alert-error" "css_element" should exist in the "Required Two-Option Checkbox" "table_row"
+ And ".alert.alert-error" "css_element" should exist in the "Required Latlong" "table_row"
+ And ".alert.alert-error" "css_element" should exist in the "Required Menu" "table_row"
+ And ".alert.alert-error" "css_element" should exist in the "Required Number" "table_row"
+ And ".alert.alert-error" "css_element" should exist in the "Required Radio" "table_row"
+ And ".alert.alert-error" "css_element" should exist in the "Required Text input" "table_row"
+ And ".alert.alert-error" "css_element" should exist in the "Required Text area" "table_row"
+ And ".alert.alert-error" "css_element" should exist in the "Required URL" "table_row"
+ And ".alert.alert-error" "css_element" should exist in the "Required Multimenu" "table_row"
+ And ".alert.alert-error" "css_element" should exist in the "Required Two-Option Multimenu" "table_row"
+ And ".alert.alert-error" "css_element" should not exist in the "Not required Checkbox" "table_row"
+ And ".alert.alert-error" "css_element" should not exist in the "Not required Latlong" "table_row"
+ And ".alert.alert-error" "css_element" should not exist in the "Not required Menu" "table_row"
+ And ".alert.alert-error" "css_element" should not exist in the "Not required Number" "table_row"
+ And ".alert.alert-error" "css_element" should not exist in the "Not required Radio" "table_row"
+ And ".alert.alert-error" "css_element" should not exist in the "Not required Text input" "table_row"
+ And ".alert.alert-error" "css_element" should not exist in the "Not required Text area" "table_row"
+ And ".alert.alert-error" "css_element" should not exist in the "Not required URL" "table_row"
+ And ".alert.alert-error" "css_element" should not exist in the "Not required Multimenu" "table_row"
+ And I follow "View list"
+ And I should see "No entries in database"
+
+ Scenario: Students recieve no error for filled in required fields
+ When I log in as "student1"
+ And I follow "Course 1"
+ And I add an entry to "Test database name" database with:
+ | Base Text input | Some input to allow us to submit the otherwise empty form |
+ | Required Checkbox Option 1 | 1 |
+ | RTOC Option 1 | 1 |
+ | Latitude | 0 |
+ | Longitude | 0 |
+ | Required Menu | 1 |
+ | Required Number | 1 |
+ | Required Radio Option 1 | 1 |
+ | Required Text input | New entry text |
+ | Required Text area | More text |
+ | Required URL | http://example.com/ |
+ | Required Multimenu | 1 |
+ | Required Two-Option Multimenu | 1 |
+ And I press "Save and view"
+ And I follow "View list"
+ Then I should not see "No entries in database"
+ And I should see "New entry text"
+
+ Scenario: Fields refill with data after having an error
+ When I log in as "student1"
+ And I follow "Course 1"
+ And I add an entry to "Test database name" database with:
+ | RTOC Option 1 | 1 |
+ | Latitude | 0 |
+ | Longitude | 0 |
+ | Required Menu | 1 |
+ | Required Number | 1 |
+ | Required Radio Option 1 | 1 |
+ | Required Text input | New entry text |
+ | Required Text area | More text |
+ | Required URL | http://example.com/ |
+ | Required Multimenu | 1 |
+ | Required Two-Option Multimenu | 1 |
+ And I press "Save and view"
+ Then the following fields match these values:
+ | Base Text input | |
+ | Latitude | 0 |
+ | Longitude | 0 |
+ | Required Menu | Option 1 |
+ | Required Number | 1 |
+ | Required Radio Option 1 | 1 |
+ | Required Text input | New entry text |
+ | Required Text area | More text |
+ | Required URL | http://example.com/ |
+ | Required Multimenu | Option 1 |
+ | Required Two-Option Multimenu | Option 1 |
# To generate the default templates.
And I follow "Templates"
And I add an entry to "Test database name" database with:
- | Test field description | Teacher entry 1 |
+ | Test field name | Teacher entry 1 |
And I press "Save and add another"
And I add an entry to "Test database name" database with:
- | Test field description | Teacher entry 2 |
+ | Test field name | Teacher entry 2 |
And I press "Save and add another"
And I add an entry to "Test database name" database with:
- | Test field description | Teacher entry 3 |
+ | Test field name | Teacher entry 3 |
And I press "Save and view"
And I log out
When I log in as "student1"
defined('MOODLE_INTERNAL') || die();
-$plugin->version = 2014111000; // The current module version (Date: YYYYMMDDXX)
+$plugin->version = 2015030900; // The current module version (Date: YYYYMMDDXX)
$plugin->requires = 2014110400; // Requires this Moodle version
$plugin->component = 'mod_data'; // Full name of the plugin (used for diagnostics)
$plugin->cron = 0;
}
}
+ // Disable shortforms.
+ $mform->setDisableShortforms();
+
$mform->addElement('header', 'pageheader');
$mform->addElement('html', $OUTPUT->container($contents, 'contents'));
$lessonid = $this->_customdata['lessonid'];
$contents = $this->_customdata['contents'];
+ // Disable shortforms.
+ $mform->setDisableShortforms();
+
$mform->addElement('header', 'pageheader');
$mform->addElement('html', $OUTPUT->container($contents, 'contents'));
$attempt->answerid = null;
}
+ // Disable shortforms.
+ $mform->setDisableShortforms();
+
$mform->addElement('header', 'pageheader');
$mform->addElement('html', $OUTPUT->container($contents, 'contents'));
$lessonid = $this->_customdata['lessonid'];
$contents = $this->_customdata['contents'];
+ // Disable shortforms.
+ $mform->setDisableShortforms();
+
$mform->addElement('header', 'pageheader');
$mform->addElement('html', $OUTPUT->container($contents, 'contents'));
$mform = $this->_form;
$contents = $this->_customdata['contents'];
+ // Disable shortforms.
+ $mform->setDisableShortforms();
+
$mform->addElement('header', 'pageheader');
$mform->addElement('html', $OUTPUT->container($contents, 'contents'));
$attrs['size'] = round(strlen($placeholder) * 1.1);
}
+ // Disable shortforms.
+ $mform->setDisableShortforms();
+
$mform->addElement('header', 'pageheader');
$mform->addElement('hidden', 'id');
$mform->setType('id', PARAM_INT);
$attempt->answerid = null;
}
+ // Disable shortforms.
+ $mform->setDisableShortforms();
+
$mform->addElement('header', 'pageheader');
$mform->addElement('html', $OUTPUT->container($contents, 'contents'));
defined('MOODLE_INTERNAL') || die();
-$version = 2015030500.00; // YYYYMMDD = weekly release date of this DEV branch.
+$version = 2015030900.00; // YYYYMMDD = weekly release date of this DEV branch.
// RR = release increments - 00 in DEV branches.
// .XX = incremental changes.
-$release = '2.9dev (Build: 20150305)'; // Human-friendly version name
+$release = '2.9dev (Build: 20150309)'; // Human-friendly version name
$branch = '29'; // This version's branch.
$maturity = MATURITY_ALPHA; // This version's maturity level.