Transmitting custom fields through a MNET jump

Transmitting custom fields through a MNET jump

by Valery Fremaux -
Number of replies: 1

Hi All,

Here is a small solution that allows transmitting custom profile fields of a roaming user.

We focus here a uniform MNET implementation in which nodes are belonging to the same operator and replicate all or part of the custom fields added to the user profile.

This can also be of some use for networks in which administrators agree on some field semantics.

Basically we consider that the shortname of the field mostly defines a rough semantic group that makes possibility of transfer consistant in a majoprity of cases. The following solution DOES NOT provides optionality switching, wich might be a better choice in the general case.

The solution is quite simple and needs only reconsidering two segments of the auth/mnet/auth.php library.

The principle is that we add provision to the user_authorise XML-RPC call for collecting user custom values, and aggregated them to the transmitted user profile as profile_field_<fieldname> addtional params.

At the other end (confirm_mnet_session()), we capture those fields and try to detect a matching semantic in the landing platform (based on matching shortname, though ignoring category concerns).

If a field is know with that name, that most probably induces semantic should match, we transfer the value to the localuser profile and update (or insert) a field data adequately.

In user_authorize(...) (auth/mnet/auth.php)

        if (!empty($user->picture)) {
            $imagefile = make_user_directory($user->id, true) . "/f1.jpg";
            if (file_exists($imagefile)) {
                $userdata['imagehash'] = sha1(file_get_contents($imagefile));
            }
        }
       
        /// get user's custom fields and aggregate them to the user profile
        $sql = "
            SELECT
                f.shortname,
                d.data
            FROM
                {$CFG->prefix}user_info_field f,
                {$CFG->prefix}user_info_data d
            WHERE
                d.userid = {$mnet_session->userid} AND
                f.id = d.fieldid
        ";
        if ($profilefields = get_records_sql_menu($sql)){
            foreach($profilefields as $fieldname => $fielddata){
                $userdata["profile_field_{$fieldname}"] = $fielddata;
            }
        }       

        $userdata['myhosts'] = array();
        if($courses = get_my_courses($user->id, 'id', 'id, visible')) {
            $userdata['myhosts'][] = array('name'=> $SITE->shortname, 'url' => $CFG->wwwroot, 'count' => count($courses));
        }

In confirm_mnet_session(...) (auth/mnet/auth.php)

            if($key == 'myhosts') {
                $localuser->mnet_foreign_host_array = array();
                foreach($val as $rhost) {
                    $name  = clean_param($rhost['name'], PARAM_ALPHANUM);
                    $url   = clean_param($rhost['url'], PARAM_URL);
                    $count = clean_param($rhost['count'], PARAM_INT);
                    $url_is_local = stristr($url , $CFG->wwwroot);
                    if (!empty($name) && !empty($count) && empty($url_is_local)) {
                        $localuser->mnet_foreign_host_array[] = array('name'  => $name,
                                                                      'url'   => $url,
                                                                      'count' => $count);
                    }
                }
            }

            // capture profile fields, check if corresponding entry is defined and update data
            if (preg_match('/^profile_field_(.*)/', $key, $matches)){
                $fieldname = $matches[1];
                if ($field = get_record('user_info_field', 'shortname', $fieldname)){
                    $datum->fieldid = $field->id;
                    $datum->userid = $localuser->id;
                    $datum->data = $remoteuser->{$key};
                    if ($oldrecord = get_record('user_info_data', 'fieldid', $field->id, 'userid', $localuser->id)){
                        $datum->id = $oldrecord->id;
                        update_record('user_info_data', $datum);
                    } else {
                        insert_record('user_info_data', $datum);
                    }
                }
            }

            $localuser->{$key} = $val;
   

Average of ratings: -
In reply to Valery Fremaux

Re: Transmitting custom fields through a MNET jump

by David Wright -

Hi,

I've implemented this suggestion on a Moodle 2.2 instance but it's not working, currently getting the 'Payload not encrypted' error.

Having looked at the code I can't see where or why anything needs to be changed, is there a working update for version 2.2 or is there likely to be another issue?

Thanks

Dave