From d6aea4cc34dc505694017abf81a87e63b950c9c7 Mon Sep 17 00:00:00 2001 From: "tim@netspot.com.au" Date: Thu, 1 Mar 2012 10:05:46 +0800 Subject: [PATCH 1/3] MDL-31654 users: custom profile menu fields will convert values to keys, so it can be processed --- admin/tool/uploaduser/index.php | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/admin/tool/uploaduser/index.php b/admin/tool/uploaduser/index.php index 633b5f2f4e2..8b98bb38a84 100644 --- a/admin/tool/uploaduser/index.php +++ b/admin/tool/uploaduser/index.php @@ -98,6 +98,31 @@ $STD_FIELDS = array('id', 'firstname', 'lastname', 'username', 'email', $PRF_FIELDS = array(); +function pre_process_profile_data($data) { + global $CFG, $DB; + + foreach ($data as $key => $value) { + if (preg_match('/^profile_field_/', $key)) { + $shortname = str_replace('profile_field_', '', $key); + if ($fields = $DB->get_records('user_info_field', array('shortname' => $shortname))) { + foreach ($fields as $field) { + if (is_file($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php')) + { + require_once($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php'); + $newfield = 'profile_field_'.$field->datatype; + if ($field->datatype == 'menu') { + $formfield = new $newfield($field->id, $data->id); + $data->$key = $formfield->convert_csv_data($value); + } + } + } + } + } + } + + return $data; +} + if ($prof_fields = $DB->get_records('user_info_field')) { foreach ($prof_fields as $prof_field) { $PRF_FIELDS[] = 'profile_field_'.$prof_field->shortname; @@ -595,6 +620,8 @@ if ($formdata = $mform2->is_cancelled()) { $upt->track('status', $struserupdated); $usersupdated++; + // pre-process custom profile menu fields data from csv file + pre_process_profile_data($existinguser); // save custom profile fields data from csv file profile_save_data($existinguser); @@ -712,6 +739,8 @@ if ($formdata = $mform2->is_cancelled()) { $user->id = $DB->insert_record('user', $user); $upt->track('username', html_writer::link(new moodle_url('/user/profile.php', array('id'=>$user->id)), s($user->username)), 'normal', false); + // pre-process custom profile menu fields data from csv file + pre_process_profile_data($user); // save custom profile fields data profile_save_data($user); From bd8dc9ba0aee376bf1829efed5b1bb1943911fc2 Mon Sep 17 00:00:00 2001 From: Rajesh Taneja Date: Thu, 1 Mar 2012 11:27:24 +0800 Subject: [PATCH 2/3] MDL-31654 users: removed hardcoding and added docblock on top of tim's patch --- admin/tool/uploaduser/index.php | 29 ++----------------------- admin/tool/uploaduser/locallib.php | 27 +++++++++++++++++++++++ user/profile/field/menu/field.class.php | 17 +++++++++++++++ 3 files changed, 46 insertions(+), 27 deletions(-) diff --git a/admin/tool/uploaduser/index.php b/admin/tool/uploaduser/index.php index 8b98bb38a84..4cb60666a57 100644 --- a/admin/tool/uploaduser/index.php +++ b/admin/tool/uploaduser/index.php @@ -98,31 +98,6 @@ $STD_FIELDS = array('id', 'firstname', 'lastname', 'username', 'email', $PRF_FIELDS = array(); -function pre_process_profile_data($data) { - global $CFG, $DB; - - foreach ($data as $key => $value) { - if (preg_match('/^profile_field_/', $key)) { - $shortname = str_replace('profile_field_', '', $key); - if ($fields = $DB->get_records('user_info_field', array('shortname' => $shortname))) { - foreach ($fields as $field) { - if (is_file($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php')) - { - require_once($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php'); - $newfield = 'profile_field_'.$field->datatype; - if ($field->datatype == 'menu') { - $formfield = new $newfield($field->id, $data->id); - $data->$key = $formfield->convert_csv_data($value); - } - } - } - } - } - } - - return $data; -} - if ($prof_fields = $DB->get_records('user_info_field')) { foreach ($prof_fields as $prof_field) { $PRF_FIELDS[] = 'profile_field_'.$prof_field->shortname; @@ -621,7 +596,7 @@ if ($formdata = $mform2->is_cancelled()) { $upt->track('status', $struserupdated); $usersupdated++; // pre-process custom profile menu fields data from csv file - pre_process_profile_data($existinguser); + $existinguser = uu_pre_process_custom_profile_data($existinguser); // save custom profile fields data from csv file profile_save_data($existinguser); @@ -740,7 +715,7 @@ if ($formdata = $mform2->is_cancelled()) { $upt->track('username', html_writer::link(new moodle_url('/user/profile.php', array('id'=>$user->id)), s($user->username)), 'normal', false); // pre-process custom profile menu fields data from csv file - pre_process_profile_data($user); + $user = uu_pre_process_custom_profile_data($user); // save custom profile fields data profile_save_data($user); diff --git a/admin/tool/uploaduser/locallib.php b/admin/tool/uploaduser/locallib.php index b46f97291a6..fea9569ff76 100644 --- a/admin/tool/uploaduser/locallib.php +++ b/admin/tool/uploaduser/locallib.php @@ -363,3 +363,30 @@ function uu_allowed_roles_cache() { } return $rolecache; } + +/** + * Pre process custom profile data, and update it with corrected value + * + * @param stdClass $data user profile data + * @return stdClass pre-processed custom profile data + */ +function uu_pre_process_custom_profile_data($data) { + global $CFG, $DB; + // find custom profile fields and check if data needs to converted. + foreach ($data as $key => $value) { + if (preg_match('/^profile_field_/', $key)) { + $shortname = str_replace('profile_field_', '', $key); + if ($fields = $DB->get_records('user_info_field', array('shortname' => $shortname))) { + foreach ($fields as $field) { + require_once($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php'); + $newfield = 'profile_field_'.$field->datatype; + $formfield = new $newfield($field->id, $data->id); + if (method_exists($formfield, 'convert_external_data')) { + $data->$key = $formfield->convert_external_data($value); + } + } + } + } + } + return $data; +} diff --git a/user/profile/field/menu/field.class.php b/user/profile/field/menu/field.class.php index 6755b64dc6f..5548fb31814 100644 --- a/user/profile/field/menu/field.class.php +++ b/user/profile/field/menu/field.class.php @@ -84,6 +84,23 @@ class profile_field_menu extends profile_field_base { $mform->setConstant($this->inputname, $this->datakey); } } + /** + * Convert external data (csv file) from value to key for processing later + * by edit_save_data_preprocess + * + * @param string $value one of the values in menu options. + * @return int options key for the menu + */ + function convert_external_data($value) { + $retval = array_search($value, $this->options); + + // If value is not found in options then return -1, so that it can be handled + // later by edit_save_data_preprocess + if ($retval === false) { + $retval = -1; + } + return $retval; + } } From 1b4d2d56d9328e4ba3e34540cab8634a4c9aef30 Mon Sep 17 00:00:00 2001 From: Rajesh Taneja Date: Tue, 13 Mar 2012 11:13:30 +0800 Subject: [PATCH 3/3] MDL-31654 users: Added check for custom profile fields, if wrong data is passed then user will not be able to proceed --- admin/tool/uploaduser/index.php | 11 +++++---- admin/tool/uploaduser/locallib.php | 32 +++++++++++++++++++++++++ user/profile/field/menu/field.class.php | 4 ++-- 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/admin/tool/uploaduser/index.php b/admin/tool/uploaduser/index.php index 4cb60666a57..9787ebb93af 100644 --- a/admin/tool/uploaduser/index.php +++ b/admin/tool/uploaduser/index.php @@ -971,6 +971,7 @@ echo $OUTPUT->heading(get_string('uploaduserspreview', 'tool_uploaduser')); $data = array(); $cir->init(); $linenum = 1; //column header is first line +$noerror = true; // Keep status of any error. while ($linenum <= $previewrows and $fields = $cir->next()) { $linenum++; $rowcols = array(); @@ -1007,7 +1008,8 @@ while ($linenum <= $previewrows and $fields = $cir->next()) { $rowcols['status'][] = get_string('fieldrequired', 'error', 'city'); } } - + // Check if rowcols have custom profile field with correct data and update error state. + $noerror = uu_check_custom_profile_data($rowcols) && $noerror; $rowcols['status'] = implode('
', $rowcols['status']); $data[] = $rowcols; } @@ -1032,9 +1034,10 @@ $table->head[] = get_string('status'); echo html_writer::tag('div', html_writer::table($table), array('class'=>'flexible-wrap')); -/// Print the form - -$mform2->display(); +// Print the form if valid values are available +if ($noerror) { + $mform2->display(); +} echo $OUTPUT->footer(); die; diff --git a/admin/tool/uploaduser/locallib.php b/admin/tool/uploaduser/locallib.php index fea9569ff76..2350b14aca9 100644 --- a/admin/tool/uploaduser/locallib.php +++ b/admin/tool/uploaduser/locallib.php @@ -390,3 +390,35 @@ function uu_pre_process_custom_profile_data($data) { } return $data; } + +/** + * Checks if data provided for custom fields is correct + * Currently checking for custom profile field or type menu + * + * @param array $data user profile data + * @return bool true if no error else false + */ +function uu_check_custom_profile_data(&$data) { + global $CFG, $DB; + $noerror = true; + + // find custom profile fields and check if data needs to converted. + foreach ($data as $key => $value) { + if (preg_match('/^profile_field_/', $key)) { + $shortname = str_replace('profile_field_', '', $key); + if ($fields = $DB->get_records('user_info_field', array('shortname' => $shortname))) { + foreach ($fields as $field) { + require_once($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php'); + $newfield = 'profile_field_'.$field->datatype; + $formfield = new $newfield($field->id, 0); + if (method_exists($formfield, 'convert_external_data') && + is_null($formfield->convert_external_data($value))) { + $data['status'][] = get_string('invaliduserfield', 'error', $shortname); + $noerror = false; + } + } + } + } + } + return $noerror; +} \ No newline at end of file diff --git a/user/profile/field/menu/field.class.php b/user/profile/field/menu/field.class.php index 5548fb31814..d1aa2ae6785 100644 --- a/user/profile/field/menu/field.class.php +++ b/user/profile/field/menu/field.class.php @@ -94,10 +94,10 @@ class profile_field_menu extends profile_field_base { function convert_external_data($value) { $retval = array_search($value, $this->options); - // If value is not found in options then return -1, so that it can be handled + // If value is not found in options then return null, so that it can be handled // later by edit_save_data_preprocess if ($retval === false) { - $retval = -1; + $retval = null; } return $retval; }