diff --git a/enrol/lti/classes/tool_provider.php b/enrol/lti/classes/tool_provider.php index 0e181acd7ac05a9b963e475ff8b4b11458823955..ab78de672253bc8e70477756245bc5f6a7442f96 100644 --- a/enrol/lti/classes/tool_provider.php +++ b/enrol/lti/classes/tool_provider.php @@ -41,6 +41,9 @@ use moodle_url; use stdClass; require_once($CFG->dirroot . '/user/lib.php'); +require_once($CFG->dirroot . '/enrol/lti/lib.php'); +require_once($CFG->dirroot . '/user/profile/lib.php'); + /** * Extends the IMS Tool provider library for the LTI enrolment. @@ -258,6 +261,15 @@ class tool_provider extends ToolProvider { // Get the updated user record. $user = $DB->get_record('user', ['id' => $user->id]); + + $fields = \enrol_lti_profile_get_fields_with_tool_data($tool->id); + foreach ($fields as $field) { + $fieldname = $field->inputname; + $field->edit_load_user_data($user); + $field->edit_save_data($user); + } + + } else { if (helper::user_match($user, $dbuser)) { $user = $dbuser; diff --git a/enrol/lti/db/install.xml b/enrol/lti/db/install.xml index c724a4be1499f73f4d59d680a13dfd531bc1d347..f48445905feb1c75d27f9f700bcb62aac31a4163 100644 --- a/enrol/lti/db/install.xml +++ b/enrol/lti/db/install.xml @@ -32,6 +32,21 @@ + + + + + + + + + + + + + + +
diff --git a/enrol/lti/db/upgrade.php b/enrol/lti/db/upgrade.php index 72ec893aff8a7c48d950913b32649881c624aab1..25de54f5a0174f0714c7bdb6a25192266efcc4e6 100644 --- a/enrol/lti/db/upgrade.php +++ b/enrol/lti/db/upgrade.php @@ -37,7 +37,7 @@ * @return boolean */ function xmldb_enrol_lti_upgrade($oldversion) { - global $CFG; + global $CFG, $DB; // Automatically generated Moodle v3.5.0 release upgrade line. // Put any upgrade step following this. @@ -54,5 +54,31 @@ function xmldb_enrol_lti_upgrade($oldversion) { // Automatically generated Moodle v3.9.0 release upgrade line. // Put any upgrade step following this. + $dbman = $DB->get_manager(); // Loads ddl manager and xmldb classes. + if ($oldversion < 2020102800) { + // Define table enrol_lti_tools_info_field to be created. + $table = new xmldb_table('enrol_lti_tools_info_field'); + + // Adding fields to table enrol_lti_tools_info_field. + $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); + $table->add_field('toolid', XMLDB_TYPE_INTEGER, '11', null, XMLDB_NOTNULL, null, null); + $table->add_field('fieldid', XMLDB_TYPE_INTEGER, '11', null, XMLDB_NOTNULL, null, null); + $table->add_field('data', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null); + $table->add_field('dataformat', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0'); + + // Adding keys to table enrol_lti_tools_info_field. + $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']); + + // Adding indexes to table enrol_lti_tools_info_field. + $table->add_index('toolfieldidx', XMLDB_INDEX_UNIQUE, ['toolid', 'fieldid']); + + // Conditionally launch create table for enrol_lti_tools_info_field. + if (!$dbman->table_exists($table)) { + $dbman->create_table($table); + } + + // Lti savepoint reached. + upgrade_plugin_savepoint(true, 2020102800, 'enrol', 'lti'); + } return true; } diff --git a/enrol/lti/lib.php b/enrol/lti/lib.php index df7c08e24a44bf88bbffc282f34ae453b7572371..66cf49fa043faacb22183e9da2d546fadb911446 100644 --- a/enrol/lti/lib.php +++ b/enrol/lti/lib.php @@ -98,6 +98,19 @@ class enrol_lti_plugin extends enrol_plugin { public function add_instance($course, array $fields = null) { global $DB; + $customfields_ids = []; + $customfields = enrol_lti_profile_get_fields(); + if (count($customfields) > 0) { + foreach ($customfields as $customfield) { + $fieldname = $customfield->object->inputname; + if (array_key_exists($fieldname, $fields)) { + $customfield->lti_default_data = $fields[$fieldname]; + unset($fields[$fieldname]); + $customfields_ids[] = $customfield->object->field->id; + } + } + } + $instanceid = parent::add_instance($course, $fields); // Add additional data to our table. @@ -109,7 +122,21 @@ class enrol_lti_plugin extends enrol_plugin { $data->$field = $value; } - $DB->insert_record('enrol_lti_tools', $data); + $toolid = $DB->insert_record('enrol_lti_tools', $data); + + if (count($customfields) > 0 && count($customfields_ids) > 0) { + foreach ($customfields as $customfield) { + if (isset($customfield->lti_default_data)) { + $fieldid = $customfield->object->field->id; + $infofield = new \stdClass(); + $customfield->lti_default_data = $customfield->object->edit_save_data_preprocess($customfield->lti_default_data, $infofield); + $infofield->toolid = $toolid; + $infofield->fieldid = $fieldid; + $infofield->data = $customfield->lti_default_data; + $DB->insert_record('enrol_lti_tools_info_field', $infofield, false); + } + } + } return $instanceid; } @@ -134,6 +161,18 @@ class enrol_lti_plugin extends enrol_plugin { // Convert to an array we can loop over. $fields = (array) $data; + $customfields_ids = []; + $customfields = enrol_lti_profile_get_fields(); + if (count($customfields) > 0) { + foreach ($customfields as $customfield) { + $fieldname = $customfield->object->inputname; + if (array_key_exists($fieldname, $fields)) { + $customfield->lti_default_data = $fields[$fieldname]; + unset($fields[$fieldname]); + $customfields_ids[] = $customfield->object->field->id; + } + } + } // Update the data in our table. $tool = new stdClass(); $tool->id = $data->toolid; @@ -142,7 +181,37 @@ class enrol_lti_plugin extends enrol_plugin { $tool->$field = $value; } - return $DB->update_record('enrol_lti_tools', $tool); + $return = $DB->update_record('enrol_lti_tools', $tool); + + if (count($customfields) > 0 && count($customfields_ids) > 0) { + list($insql, $params) = $DB->get_in_or_equal($customfields_ids, SQL_PARAMS_NAMED); + $sql = "SELECT `fieldid`, `id`, `toolid`, `data`, `dataformat` + FROM {enrol_lti_tools_info_field} WHERE `toolid` = :toolid AND `fieldid` $insql"; + $params['toolid'] = $tool->id; + $infofields = $DB->get_records_sql($sql, $params); + foreach ($customfields as $customfield) { + if (isset($customfield->lti_default_data)) { + $fieldid = $customfield->object->field->id; + if (!array_key_exists($fieldid, $infofields)) { + $infofield = new \stdClass(); + $customfield->lti_default_data = $customfield->object->edit_save_data_preprocess($customfield->lti_default_data, $infofield); + $infofield->toolid = $tool->id; + $infofield->fieldid = $fieldid; + $infofield->data = $customfield->lti_default_data; + $return &= $DB->insert_record('enrol_lti_tools_info_field', $infofield, false); + } + else { + $infofield = $infofields[$fieldid]; + $customfield->lti_default_data = $customfield->object->edit_save_data_preprocess($customfield->lti_default_data, $infofield); + $infofield->data = $customfield->lti_default_data; + $return &= $DB->update_record('enrol_lti_tools_info_field', $infofield); + } + } + } + } + + return $return; + } /** @@ -160,6 +229,9 @@ class enrol_lti_plugin extends enrol_plugin { // Delete any users associated with this tool. $DB->delete_records('enrol_lti_users', array('toolid' => $tool->id)); + // Delete customfield default values + $DB->delete_records('enrol_lti_tools_info_field', array('toolid' => $tool->id)); + // Get tool and consumer mappings. $rsmapping = $DB->get_recordset('enrol_lti_tool_consumer_map', array('toolid' => $tool->id)); @@ -328,6 +400,9 @@ class enrol_lti_plugin extends enrol_plugin { $mform->setDefault('institution', $institution); $mform->setAdvanced('institution'); + // Add customfields + enrol_lti_profile_fields($mform); + // Check if we are editing an instance. if (!empty($instance->id)) { // Get the details from the enrol_lti_tools table. @@ -337,6 +412,10 @@ class enrol_lti_plugin extends enrol_plugin { $mform->setType('toolid', PARAM_INT); $mform->setConstant('toolid', $ltitool->id); + $fields = enrol_lti_profile_get_fields_with_tool_data($ltitool->id); + foreach ($fields as $field) { + $field->edit_load_user_data($ltitool); + } $mform->setDefaults((array) $ltitool); } } @@ -415,3 +494,95 @@ function enrol_lti_extend_navigation_course($navigation, $course, $context) { } } } + + +/** + * Retrieves a list of profile fields that must be displayed in the sign-up form. + * + * @return array list of profile fields info + * @since Moodle 3.2 + */ +function enrol_lti_profile_get_fields() { + global $CFG, $DB; + + $profilefields = array(); + // Only retrieve required custom fields (with category information) + // results are sort by categories, then by fields. + $sql = "SELECT uf.id as fieldid, ic.id as categoryid, ic.name as categoryname, uf.datatype + FROM {user_info_field} uf + JOIN {user_info_category} ic + ON uf.categoryid = ic.id AND uf.visible<>0 + ORDER BY ic.sortorder ASC, uf.sortorder ASC"; + + if ($fields = $DB->get_records_sql($sql)) { + foreach ($fields as $field) { + require_once($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php'); + $newfield = 'profile_field_'.$field->datatype; + $fieldobject = new $newfield($field->fieldid); + + $profilefields[] = (object) array( + 'categoryid' => $field->categoryid, + 'categoryname' => $field->categoryname, + 'fieldid' => $field->fieldid, + 'datatype' => $field->datatype, + 'object' => $fieldobject + ); + } + } + return $profilefields; +} + +/** + * Adds code snippet to a moodle form object for custom profile fields that + * should appear on the signup page + * @param moodleform $mform moodle form object + */ +function enrol_lti_profile_fields($mform) { + + if ($fields = enrol_lti_profile_get_fields()) { + foreach ($fields as $field) { + // Check if we change the categories. + if (!isset($currentcat) || $currentcat != $field->categoryid) { + $currentcat = $field->categoryid; + $mform->addElement('header', 'category_'.$field->categoryid, format_string($field->categoryname)); + }; + $field->object->edit_field($mform); + } + } +} + +/** + * Returns an array of all custom field records with any defined data (or empty data), for the specified user id. + * @param int $userid + * @return profile_field_base[] + */ +function enrol_lti_profile_get_fields_with_tool_data($toolid) { + global $DB, $CFG; + + // Join any user info data present with each user info field for the user object. + $sql = 'SELECT uif.*, uic.name AS categoryname '; + if ($toolid > 0) { + $sql .= ', tif.id AS hasuserdata, tif.data, tif.dataformat '; + } + $sql .= 'FROM {user_info_field} uif '; + $sql .= 'LEFT JOIN {user_info_category} uic ON uif.categoryid = uic.id '; + if ($toolid > 0) { + $sql .= 'LEFT JOIN {enrol_lti_tools_info_field} tif ON uif.id = tif.fieldid AND tif.toolid = :toolid '; + } + $sql .= 'ORDER BY uic.sortorder ASC, uif.sortorder ASC '; + $fields = $DB->get_records_sql($sql, ['toolid' => $toolid]); + $data = []; + foreach ($fields as $field) { + require_once($CFG->dirroot . '/user/profile/field/' . $field->datatype . '/field.class.php'); + $classname = '\profile_field_' . $field->datatype; + $field->hasuserdata = !empty($field->hasuserdata); + /** @var profile_field_base $fieldobject */ + $userid = 1; // fake userid to trigger datas in constructor + $fieldobject = new $classname($field->id, $userid, $field); + $fieldobject->set_userid(0); // remove fake userid + $fieldobject->set_category_name($field->categoryname); + unset($field->categoryname); + $data[] = $fieldobject; + } + return $data; +} diff --git a/enrol/lti/version.php b/enrol/lti/version.php index be99222592b8cc6cd07ac52d15699da268d6cd27..9c00afe271705444535565dd98302b9b0737c36b 100644 --- a/enrol/lti/version.php +++ b/enrol/lti/version.php @@ -24,6 +24,6 @@ defined('MOODLE_INTERNAL') || die(); -$plugin->version = 2020061500; // The current plugin version (Date: YYYYMMDDXX). +$plugin->version = 2020102800; // The current plugin version (Date: YYYYMMDDXX). $plugin->requires = 2020060900; // Requires this Moodle version. $plugin->component = 'enrol_lti'; // Full name of the plugin (used for diagnostics).