From 334415e93f144244851ded97161735aceab3179a Mon Sep 17 00:00:00 2001 From: ikawhero Date: Mon, 16 Apr 2007 02:49:33 +0000 Subject: [PATCH] Merging changes from 1.8 Display custom profile fields in profile page - see MDL-9285 Menu type stores the value rather than the index - see comments on MDL-9285 General tidy up and renaming of funtions in field class. --- lib/db/upgrade.php | 30 ++++ user/profile/field/menu/field.class.php | 55 ++++-- user/profile/field/text/field.class.php | 2 +- user/profile/lib.php | 217 +++++++++++++++++------- user/view.php | 5 + version.php | 2 +- 6 files changed, 239 insertions(+), 72 deletions(-) diff --git a/lib/db/upgrade.php b/lib/db/upgrade.php index d992055110..0a7a54c110 100644 --- a/lib/db/upgrade.php +++ b/lib/db/upgrade.php @@ -712,6 +712,36 @@ function xmldb_main_upgrade($oldversion=0) { } + /* Changes to the custom profile menu type - store values rather than indices. + We could do all this with one tricky SQL statement but it's a one-off so no + harm in using PHP loops */ + if ($result && $oldversion < 2007041600) { + + /// Get the menu fields + if ($fields = get_records('user_info_field', 'datatype', 'menu')) { + foreach ($fields as $field) { + + /// Get user data for the menu field + if ($data = get_records('user_info_data', 'fieldid', $field->id)) { + + /// Get the menu options + $options = explode("\n", $this->field->param1); + foreach ($data as $d) { + $key = array_search($d->data, $options); + + /// If the data is an integer and is not one of the options, + /// set the respective option value + if (is_int($d->data) and (($key === NULL) or ($key === false)) and isset($options[$d->data])) { + $d->data = $options[$d->data]; + $result = $result && update_record('user_info_data', $d); + } + } + } + } + } + + } + return $result; } diff --git a/user/profile/field/menu/field.class.php b/user/profile/field/menu/field.class.php index 37f37925cd..98780d84ee 100644 --- a/user/profile/field/menu/field.class.php +++ b/user/profile/field/menu/field.class.php @@ -2,35 +2,68 @@ class profile_field_menu extends profile_field_base { var $options; - var $selected; + var $datakey; - function profile_field_menu($fieldid) { + /** + * Constructor method. + * Pulls out the options for the menu from the database and sets the + * the corresponding key for the data if it exists + */ + function profile_field_menu($fieldid, $userid) { //first call parent constructor - $this->profile_field_base($fieldid); + $this->profile_field_base($fieldid, $userid); /// Param 1 for menu type is the options $options = explode("\n", $this->field->param1); $this->options = array(); foreach($options as $key => $option) { $this->options[$key] = format_string($option);//multilang formatting - if ($option == $this->field->defaultdata) { - $this->selected = $key; - } } + /// Set the data key + if ($this->data !== NULL) { + $this->datakey = (int)array_search($this->data, $this->options); + } } - function display_field_add(&$mform) { - /// Create the form field + /** + * Create the code snippet for this field instance + * Overwrites the base class method + * @param object moodleform instance + */ + function edit_field_add(&$mform) { $mform->addElement('select', $this->inputname, format_string($this->field->name), $this->options); - $mform->setDefault($this->inputname, $this->selected); } - /// Override base class method - function display_field_default(&$mform) { + /** + * Set the default value for this field instance + * Overwrites the base class method + */ + function edit_field_set_default(&$mform) { $defaultkey = (int)array_search($field->defaultdata, $this->options); $mform->setDefault($this->inputname, $defaultkey); } + + /** + * The data from the form returns the key. This should be converted to the + * respective option string to be saved in database + * Overwrites base class accessor method + * @param integer the key returned from the select input in the form + */ + function edit_save_data_preprocess($key) { + return isset($this->options[$key]) ? $this->options[$key] : NULL; + } + + /** + * When passing the user object to the form class for the edit profile page + * we should load the key for the saved data + * Overwrites the base class method + * @param object user object + */ + function edit_load_user_data(&$user) { + $user->{$this->inputname} = $this->datakey; + } + } ?> diff --git a/user/profile/field/text/field.class.php b/user/profile/field/text/field.class.php index 598bd5cb52..da7c1636e6 100644 --- a/user/profile/field/text/field.class.php +++ b/user/profile/field/text/field.class.php @@ -2,7 +2,7 @@ class profile_field_text extends profile_field_base { - function display_field_add(&$mform) { + function edit_field_add(&$mform) { $size = $this->field->param1; $maxlength = $this->field->param2; diff --git a/user/profile/lib.php b/user/profile/lib.php index bd80876cbb..21f50c90cf 100644 --- a/user/profile/lib.php +++ b/user/profile/lib.php @@ -6,59 +6,70 @@ define ('PROFILE_VISIBLE_ALL', '2'); // only visible for users with moodle/u define ('PROFILE_VISIBLE_PRIVATE', '1'); // either we are viewing our own profile or we have moodle/user:update capability define ('PROFILE_VISIBLE_NONE', '0'); // only visible for moodle/user:update capability + + /** * Base class for the cusomisable profile fields. */ class profile_field_base { + /// These 2 variables are really what we're interested in. + /// Everything else can be extracted from them + var $fieldid; + var $userid; + var $field; var $inputname; + var $data; /** * Constructor method. * @param integer id of the profile from the user_info_field table * @param integer id of the user for whom we are displaying data */ - function profile_field_base($fieldid) { - if (!$field = get_record('user_info_field', 'id', $fieldid)) { - error('Incorrect profile field id!'); - } + function profile_field_base($fieldid=0, $userid=0) { + global $USER; - $this->field = $field; - $this->inputname = 'profile_field_'.$field->shortname; + $this->set_fieldid($fieldid); + $this->set_userid($userid); + $this->load_data(); } + +/***** The following methods must be overwritten by child classes *****/ + /** - * Check if the current field is visible to the current user - * @return boolean + * Abstract method: Adds the profile field to the moodle form class + * @param form instance of the moodleform class */ - function is_visible_for($userid) { - global $USER; - - switch ($this->field->visible) { - case PROFILE_VISIBLE_ALL: - return true; - case PROFILE_VISIBLE_PRIVATE: - return ($userid == $USER->id); - default: - return has_capability('moodle/user:update', get_context_instance(CONTEXT_SYSTEM, SITEID)); - } + function edit_field_add(&$mform) { + error('This abstract method must be overriden'); } + +/***** The following methods may be overwritten by child classes *****/ + + /** + * Display the data for this field + */ + function display_data() { + return s(format_string($this->data)); + } + /** - * Print out the form field in the profile page + * Print out the form field in the edit profile page * @param object instance of the moodleform class * $return boolean */ - function display_field(&$mform) { + function edit_field(&$mform) { if ($this->field->visible != PROFILE_VISIBLE_NONE or has_capability('moodle/user:update', get_context_instance(CONTEXT_SYSTEM, SITEID))) { - $this->display_field_add($mform); - $this->display_field_set_default($mform); - $this->display_field_set_required($mform); - $this->display_field_set_locked($mform); + $this->edit_field_add($mform); + $this->edit_field_set_default($mform); + $this->edit_field_set_required($mform); + $this->edit_field_set_locked($mform); } } @@ -67,14 +78,14 @@ class profile_field_base { * @param mixed data coming from the form * @return mixed returns data id if success of db insert/update, false on fail, 0 if not permitted */ - function save_data($usernew) { - - $usernew = $this->save_data_preprocess($usernew); + function edit_save_data($usernew) { if (!isset($usernew->{$this->inputname})) { // field not present in form, probably locked and invisible - skip it return; } + + $usernew->{$this->inputname} = $this->edit_save_data_preprocess($usernew->{$this->inputname}); $data = new object(); $data->userid = $usernew->id; @@ -91,37 +102,20 @@ class profile_field_base { } } - /***** The following methods may be overwritten by child classes *****/ - - /** - * Adds the profile field to the moodle form class - * @param form instance of the moodleform class - */ - function display_field_add(&$mform) { - error('This abstract method must be overriden'); - } - /** * Validate the form field from profile page * @return string contains error message otherwise NULL **/ - function validate_field($usernew) { + function edit_validate_field($usernew) { //no errors by default return array(); } - - function load_data(&$user) { - if ($data = get_field('user_info_data', 'data', 'userid', $user->id, 'fieldid', $this->field->id)) { - $user->{$this->inputname} = $data; - } - } - /** * Sets the default data for the field in the form object * @param object instance of the moodleform class */ - function display_field_set_default(&$mform) { + function edit_field_set_default(&$mform) { if (!empty($default)) { $mform->setDefault($this->inputname, $this->field->defaultdata); } @@ -131,8 +125,8 @@ class profile_field_base { * Sets the required flag for the field in the form object * @param object instance of the moodleform class */ - function display_field_set_required(&$mform) { - if ($this->field->required and !has_capability('moodle/user:update', get_context_instance(CONTEXT_SYSTEM, SITEID))) { + function edit_field_set_required(&$mform) { + if ($this->is_required() and !has_capability('moodle/user:update', get_context_instance(CONTEXT_SYSTEM, SITEID))) { $mform->addRule($this->inputname, get_string('required'), 'required', null, 'client'); } } @@ -141,8 +135,8 @@ class profile_field_base { * HardFreeze the field if locked. * @param object instance of the moodleform class */ - function display_field_set_locked(&$mform) { - if ($this->field->locked and !has_capability('moodle/user:update', get_context_instance(CONTEXT_SYSTEM, SITEID))) { + function edit_field_set_locked(&$mform) { + if ($this->is_locked() and !has_capability('moodle/user:update', get_context_instance(CONTEXT_SYSTEM, SITEID))) { $mform->hardFreeze($this->inputname); } } @@ -152,10 +146,98 @@ class profile_field_base { * @param mixed * @return mixed */ - function save_data_preprocess($data) { + function edit_save_data_preprocess($data) { return $data; } + /** + * Loads a user object with data for this field ready for the edit profile + * form + * @param object a user object + */ + function edit_load_user_data(&$user) { + if ($this->data !== NULL) { + $user->{$this->inputname} = $this->data; + } + } + + +/***** The following methods generally should not be overwritten by child classes *****/ + + /** + * Accessor method: set the userid for this instance + * @param integer id from the user table + */ + function set_userid($userid) { + $this->userid = $userid; + } + + /** + * Accessor method: set the fieldid for this instance + * @param integer id from the user_info_field table + */ + function set_fieldid($fieldid) { + $this->fieldid = $fieldid; + } + + /** + * Accessor method: Load the field record and user data associated with the + * object's fieldid and userid + */ + function load_data() { + /// Load the field object + if (($this->fieldid == 0) or (!($field = get_record('user_info_field', 'id', $this->fieldid)))) { + $this->field = NULL; + $this->inputname = ''; + } else { + $this->field = $field; + $this->inputname = 'profile_field_'.$field->shortname; + } + + if (!empty($this->field)) { + if ($datafield = get_field('user_info_data', 'data', 'userid', $this->userid, 'fieldid', $this->fieldid)) { + $this->data = $datafield; + } else { + $this->data = $this->field->defaultdata; + } + } else { + $this->data = NULL; + } + } + + /** + * Check if the field data is visible to the current user + * @return boolean + */ + function is_visible() { + global $USER; + + switch ($this->field->visible) { + case PROFILE_VISIBLE_ALL: + return true; + case PROFILE_VISIBLE_PRIVATE: + return ($this->userid == $USER->id); + default: + return has_capability('moodle/user:update', get_context_instance(CONTEXT_SYSTEM, SITEID)); + } + } + + /** + * Check if the field is required on the edit profile page + * @return boolean + */ + function is_required() { + return (boolean)$this->field->required; + } + + /** + * Check if the field is locked on the edit profile page + * @return boolean + */ + function is_locked() { + return (boolean)$this->field->locked; + } + } /// End of class definition @@ -168,8 +250,8 @@ function profile_load_data(&$user) { 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); - $formfield->load_data($user); + $formfield = new $newfield($field->id, $user->id); + $formfield->edit_load_user_data($user); } } } @@ -189,7 +271,7 @@ function profile_definition(&$mform) { require_once($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php'); $newfield = 'profile_field_'.$field->datatype; $formfield = new $newfield($field->id); - $formfield->display_field($mform); + $formfield->edit_field($mform); } } @@ -219,8 +301,8 @@ function profile_validation($usernew) { 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); - $err += $formfield->validate_field($usernew); + $formfield = new $newfield($field->id, $usernew->id); + $err += $formfield->edit_validate_field($usernew); } } return $err; @@ -233,13 +315,30 @@ function profile_save_data($usernew) { 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); - $formfield->save_data($usernew); + $formfield = new $newfield($field->id, $usernew->id); + $formfield->edit_save_data($usernew); } } } +function profile_display_fields($userid) { + global $CFG, $USER; + if ($categories = get_records_select('user_info_category', '', 'sortorder ASC')) { + foreach ($categories as $category) { + if ($fields = get_records_select('user_info_field', "categoryid=$category->id", 'sortorder ASC')) { + 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, $userid); + if ($formfield->is_visible() and ($formfield->data !== NULL)) { + print_row(s($formfield->field->name.':'), $formfield->display_data()); + } + } + } + } + } +} diff --git a/user/view.php b/user/view.php index 3dec104c42..208809e89c 100644 --- a/user/view.php +++ b/user/view.php @@ -3,6 +3,7 @@ // Display profile for a particular user require_once("../config.php"); + require_once($CFG->dirroot.'/user/profile/lib.php'); $id = optional_param('id', 0, PARAM_INT); // user id $course = optional_param('course', SITEID, PARAM_INT); // course id (defaults to Site) $enable = optional_param('enable', ''); // enable email @@ -294,6 +295,10 @@ print_row(get_string('msnid').':', s($user->msn)); } + /// Print the Custom User Fields + profile_display_fields($user->id); + + if ($mycourses = get_my_courses($user->id,'visible DESC,sortorder ASC', '*', false, 21)) { $shown=0; $courselisting = ''; diff --git a/version.php b/version.php index 5a011f8d46..8f774c7fd8 100644 --- a/version.php +++ b/version.php @@ -6,7 +6,7 @@ // This is compared against the values stored in the database to determine // whether upgrades should be performed (see lib/db/*.php) - $version = 2007041100; // YYYYMMDD = date + $version = 2007041600; // YYYYMMDD = date // XY = increments within a single day $release = '1.9 dev'; // Human-friendly version name -- 2.39.5