diff --git a/admin/auth_config.php b/admin/auth_config.php
index 3ee8ebc8c0f..503dd91cc1f 100644
--- a/admin/auth_config.php
+++ b/admin/auth_config.php
@@ -171,8 +171,6 @@ function print_auth_lock_options($auth, $user_fields, $helptext, $retrieveopts,
// limit for the setting name is 100.
continue;
}
- } elseif ($fieldname == 'url') {
- $fieldname = get_string('webpage');
} else {
$fieldname = get_string($fieldname);
}
diff --git a/admin/settings/users.php b/admin/settings/users.php
index 6e58d4cd89e..2f265ee7efd 100644
--- a/admin/settings/users.php
+++ b/admin/settings/users.php
@@ -196,12 +196,6 @@ if ($hassiteconfig
'country' => new lang_string('country'),
'moodlenetprofile' => new lang_string('moodlenetprofile', 'user'),
'timezone' => new lang_string('timezone'),
- 'webpage' => new lang_string('webpage'),
- 'icqnumber' => new lang_string('icqnumber'),
- 'skypeid' => new lang_string('skypeid'),
- 'yahooid' => new lang_string('yahooid'),
- 'aimid' => new lang_string('aimid'),
- 'msnid' => new lang_string('msnid'),
'firstaccess' => new lang_string('firstaccess'),
'lastaccess' => new lang_string('lastaccess'),
'lastip' => new lang_string('lastip'),
diff --git a/admin/tool/uploaduser/classes/process.php b/admin/tool/uploaduser/classes/process.php
index 4204c8b8ae5..cb56918a276 100644
--- a/admin/tool/uploaduser/classes/process.php
+++ b/admin/tool/uploaduser/classes/process.php
@@ -142,9 +142,8 @@ class process {
$this->standardfields = array('id', 'username', 'email', 'emailstop',
'city', 'country', 'lang', 'timezone', 'mailformat',
'maildisplay', 'maildigest', 'htmleditor', 'autosubscribe',
- 'institution', 'department', 'idnumber', 'skype',
- 'msn', 'aim', 'yahoo', 'icq', 'phone1', 'phone2', 'address',
- 'url', 'description', 'descriptionformat', 'password',
+ 'institution', 'department', 'idnumber', 'phone1', 'phone2', 'address',
+ 'description', 'descriptionformat', 'password',
'auth', // Watch out when changing auth type or using external auth plugins!
'oldusername', // Use when renaming users - this is the original username.
'suspended', // 1 means suspend user account, 0 means activate user account, nothing means keep as is.
diff --git a/admin/tool/uploaduser/user_form.php b/admin/tool/uploaduser/user_form.php
index 9e90d84eeb1..8dcf4ce76a2 100644
--- a/admin/tool/uploaduser/user_form.php
+++ b/admin/tool/uploaduser/user_form.php
@@ -300,10 +300,6 @@ class admin_uploaduser_form2 extends moodleform {
$mform->addHelpButton('description', 'userdescription');
$mform->setAdvanced('description');
- $mform->addElement('text', 'url', get_string('webpage'), 'maxlength="255" size="50"');
- $mform->setType('url', PARAM_URL);
- $mform->setAdvanced('url');
-
$mform->addElement('text', 'idnumber', get_string('idnumber'), 'maxlength="255" size="25"');
$mform->setType('idnumber', core_user::get_property_type('idnumber'));
$mform->setForceLtr('idnumber');
diff --git a/admin/user/user_bulk_download.php b/admin/user/user_bulk_download.php
index 4e5e8d37ae9..ffa3f2335b1 100644
--- a/admin/user/user_bulk_download.php
+++ b/admin/user/user_bulk_download.php
@@ -48,12 +48,6 @@ if ($dataformat) {
'phone1' => 'phone1',
'phone2' => 'phone2',
'city' => 'city',
- 'url' => 'url',
- 'icq' => 'icq',
- 'skype' => 'skype',
- 'aim' => 'aim',
- 'yahoo' => 'yahoo',
- 'msn' => 'msn',
'country' => 'country');
if ($extrafields = $DB->get_records('user_info_field')) {
diff --git a/auth/mnet/classes/privacy/provider.php b/auth/mnet/classes/privacy/provider.php
index c774de14573..c1a95c6f6f7 100644
--- a/auth/mnet/classes/privacy/provider.php
+++ b/auth/mnet/classes/privacy/provider.php
@@ -81,7 +81,6 @@ class provider implements
$externalfields = [
'address' => 'privacy:metadata:mnet_external:address',
- 'aim' => 'privacy:metadata:mnet_external:aim',
'alternatename' => 'privacy:metadata:mnet_external:alternatename',
'autosubscribe' => 'privacy:metadata:mnet_external:autosubscribe',
'calendartype' => 'privacy:metadata:mnet_external:calendartype',
@@ -95,7 +94,6 @@ class provider implements
'firstaccess' => 'privacy:metadata:mnet_external:firstaccess',
'firstname' => 'privacy:metadata:mnet_external:firstname',
'firstnamephonetic' => 'privacy:metadata:mnet_external:firstnamephonetic',
- 'icq' => 'privacy:metadata:mnet_external:icq',
'id' => 'privacy:metadata:mnet_external:id',
'idnumber' => 'privacy:metadata:mnet_external:idnumber',
'imagealt' => 'privacy:metadata:mnet_external:imagealt',
@@ -108,19 +106,15 @@ class provider implements
'maildigest' => 'privacy:metadata:mnet_external:maildigest',
'maildisplay' => 'privacy:metadata:mnet_external:maildisplay',
'middlename' => 'privacy:metadata:mnet_external:middlename',
- 'msn' => 'privacy:metadata:mnet_external:msn',
'phone1' => 'privacy:metadata:mnet_external:phone1',
'pnone2' => 'privacy:metadata:mnet_external:phone2',
'picture' => 'privacy:metadata:mnet_external:picture',
'policyagreed' => 'privacy:metadata:mnet_external:policyagreed',
- 'skype' => 'privacy:metadata:mnet_external:skype',
'suspended' => 'privacy:metadata:mnet_external:suspended',
'timezone' => 'privacy:metadata:mnet_external:timezone',
'trackforums' => 'privacy:metadata:mnet_external:trackforums',
'trustbitmask' => 'privacy:metadata:mnet_external:trustbitmask',
- 'url' => 'privacy:metadata:mnet_external:url',
'username' => 'privacy:metadata:mnet_external:username',
- 'yahoo' => 'privacy:metadata:mnet_external:yahoo',
];
$collection->add_external_location_link('moodle', $externalfields, 'privacy:metadata:external:moodle');
diff --git a/auth/mnet/lang/en/auth_mnet.php b/auth/mnet/lang/en/auth_mnet.php
index 4836214200b..d07f3a65355 100644
--- a/auth/mnet/lang/en/auth_mnet.php
+++ b/auth/mnet/lang/en/auth_mnet.php
@@ -39,7 +39,6 @@ $string['pluginname'] = 'MNet authentication';
$string['privacy:metadata:external:mahara'] = 'This plugin can send data externally to a linked Mahara application.';
$string['privacy:metadata:external:moodle'] = 'This plugin can send data externally to a linked Moodle application.';
$string['privacy:metadata:mnet_external:address'] = 'The address of the user.';
-$string['privacy:metadata:mnet_external:aim'] = 'The AIM identifier of the user';
$string['privacy:metadata:mnet_external:alternatename'] = 'An alternative name for the user.';
$string['privacy:metadata:mnet_external:autosubscribe'] = 'A preference as to if the user should be auto-subscribed to forums the user posts in.';
$string['privacy:metadata:mnet_external:calendartype'] = 'A user preference for the type of calendar to use.';
@@ -53,7 +52,6 @@ $string['privacy:metadata:mnet_external:emailstop'] = 'A preference to stop emai
$string['privacy:metadata:mnet_external:firstaccess'] = 'The time that this user first accessed the site.';
$string['privacy:metadata:mnet_external:firstname'] = 'The first name of the user.';
$string['privacy:metadata:mnet_external:firstnamephonetic'] = 'The phonetic details about the user\'s first name.';
-$string['privacy:metadata:mnet_external:icq'] = 'The ICQ number of the user.';
$string['privacy:metadata:mnet_external:id'] = 'The user ID';
$string['privacy:metadata:mnet_external:idnumber'] = 'An identification number given by the institution';
$string['privacy:metadata:mnet_external:imagealt'] = 'Alternative text for the user\'s image.';
@@ -66,19 +64,15 @@ $string['privacy:metadata:mnet_external:lastnamephonetic'] = 'The phonetic detai
$string['privacy:metadata:mnet_external:maildigest'] = 'A setting for the mail digest for this user.';
$string['privacy:metadata:mnet_external:maildisplay'] = 'A preference for the user about displaying their email address to other users.';
$string['privacy:metadata:mnet_external:middlename'] = 'The middle name of the user';
-$string['privacy:metadata:mnet_external:msn'] = 'The MSN identifier of the user';
$string['privacy:metadata:mnet_external:phone1'] = 'A phone number for the user.';
$string['privacy:metadata:mnet_external:phone2'] = 'An additional phone number for the user.';
$string['privacy:metadata:mnet_external:picture'] = 'The picture details associated with this user.';
$string['privacy:metadata:mnet_external:policyagreed'] = 'A flag to determine if the user has agreed to the site policy.';
-$string['privacy:metadata:mnet_external:skype'] = 'The Skype identifier of the user';
$string['privacy:metadata:mnet_external:suspended'] = 'A flag to show if the user has been suspended on this system.';
$string['privacy:metadata:mnet_external:timezone'] = 'The timezone of the user';
$string['privacy:metadata:mnet_external:trackforums'] = 'A preference for forums and tracking them.';
$string['privacy:metadata:mnet_external:trustbitmask'] = 'The trust bit mask';
-$string['privacy:metadata:mnet_external:url'] = 'A URL related to this user.';
$string['privacy:metadata:mnet_external:username'] = 'The username for this user.';
-$string['privacy:metadata:mnet_external:yahoo'] = 'The Yahoo identifier of the user';
$string['privacy:metadata:mnet_log'] = 'Details of remote actions carried out by a local user logged in a remote system.';
$string['privacy:metadata:mnet_log:action'] = 'Action carried out by the user.';
$string['privacy:metadata:mnet_log:cmid'] = 'ID of the course module.';
@@ -99,4 +93,12 @@ $string['privacy:metadata:mnet_session:token'] = 'Unique session identifier';
$string['privacy:metadata:mnet_session:useragent'] = 'User agent used to access the remote system';
$string['privacy:metadata:mnet_session:userid'] = 'ID of the user jumping to remote system.';
$string['privacy:metadata:mnet_session:username'] = 'Username of the user jumping to remote system.';
-$string['unknownhost'] = 'Unknown host';
\ No newline at end of file
+$string['unknownhost'] = 'Unknown host';
+
+// Deprecated since Moodle 4.0.
+$string['privacy:metadata:mnet_external:aim'] = 'The AIM identifier of the user';
+$string['privacy:metadata:mnet_external:icq'] = 'The ICQ number of the user.';
+$string['privacy:metadata:mnet_external:msn'] = 'The MSN identifier of the user';
+$string['privacy:metadata:mnet_external:skype'] = 'The Skype identifier of the user';
+$string['privacy:metadata:mnet_external:url'] = 'A URL related to this user.';
+$string['privacy:metadata:mnet_external:yahoo'] = 'The Yahoo identifier of the user';
diff --git a/auth/oauth2/classes/api.php b/auth/oauth2/classes/api.php
index e5b0789b576..5c3545e1250 100644
--- a/auth/oauth2/classes/api.php
+++ b/auth/oauth2/classes/api.php
@@ -258,7 +258,6 @@ class api {
$user->mnethostid = $CFG->mnet_localhost_id;
$user->lastname = isset($userinfo['lastname']) ? $userinfo['lastname'] : '';
$user->firstname = isset($userinfo['firstname']) ? $userinfo['firstname'] : '';
- $user->url = isset($userinfo['url']) ? $userinfo['url'] : '';
$user->alternatename = isset($userinfo['alternatename']) ? $userinfo['alternatename'] : '';
$user->secret = random_string(15);
@@ -307,7 +306,6 @@ class api {
$user->mnethostid = $CFG->mnet_localhost_id;
$user->lastname = isset($userinfo['lastname']) ? $userinfo['lastname'] : '';
$user->firstname = isset($userinfo['firstname']) ? $userinfo['firstname'] : '';
- $user->url = isset($userinfo['url']) ? $userinfo['url'] : '';
$user->alternatename = isset($userinfo['alternatename']) ? $userinfo['alternatename'] : '';
$user->secret = random_string(15);
diff --git a/availability/condition/profile/classes/frontend.php b/availability/condition/profile/classes/frontend.php
index 37fda5371f3..d6a311d9c14 100644
--- a/availability/condition/profile/classes/frontend.php
+++ b/availability/condition/profile/classes/frontend.php
@@ -49,12 +49,6 @@ class frontend extends \core_availability\frontend {
'email' => \core_user\fields::get_display_name('email'),
'city' => \core_user\fields::get_display_name('city'),
'country' => \core_user\fields::get_display_name('country'),
- 'url' => \core_user\fields::get_display_name('url'),
- 'icq' => \core_user\fields::get_display_name('icq'),
- 'skype' => \core_user\fields::get_display_name('skype'),
- 'aim' => \core_user\fields::get_display_name('aim'),
- 'yahoo' => \core_user\fields::get_display_name('yahoo'),
- 'msn' => \core_user\fields::get_display_name('msn'),
'idnumber' => \core_user\fields::get_display_name('idnumber'),
'institution' => \core_user\fields::get_display_name('institution'),
'department' => \core_user\fields::get_display_name('department'),
diff --git a/backup/moodle2/backup_stepslib.php b/backup/moodle2/backup_stepslib.php
index 4339b0c232d..d8f4e5aeaa3 100644
--- a/backup/moodle2/backup_stepslib.php
+++ b/backup/moodle2/backup_stepslib.php
@@ -1360,11 +1360,10 @@ class backup_users_structure_step extends backup_structure_step {
// Then, the fields potentially needing anonymization
$anonfields = array(
- 'username', 'idnumber', 'email', 'icq', 'skype',
- 'yahoo', 'aim', 'msn', 'phone1',
+ 'username', 'idnumber', 'email', 'phone1',
'phone2', 'institution', 'department', 'address',
'city', 'country', 'lastip', 'picture',
- 'url', 'description', 'descriptionformat', 'imagealt', 'auth');
+ 'description', 'descriptionformat', 'imagealt', 'auth');
$anonfields = array_merge($anonfields, \core_user\fields::get_name_fields());
// Add anonymized fields to $userfields with custom final element
diff --git a/backup/util/helper/backup_anonymizer_helper.class.php b/backup/util/helper/backup_anonymizer_helper.class.php
index 9ccd8876141..74b73962d00 100644
--- a/backup/util/helper/backup_anonymizer_helper.class.php
+++ b/backup/util/helper/backup_anonymizer_helper.class.php
@@ -98,26 +98,6 @@ class backup_anonymizer_helper {
return 'anon' . $counter . '@doesntexist.invalid'; // Just a counter.
}
- public static function process_user_icq($value) {
- return ''; // Clean icq
- }
-
- public static function process_user_skype($value) {
- return ''; // Clean skype
- }
-
- public static function process_user_yahoo($value) {
- return ''; // Clean yahoo
- }
-
- public static function process_user_aim($value) {
- return ''; // Clean aim
- }
-
- public static function process_user_msn($value) {
- return ''; // Clean msn
- }
-
public static function process_user_phone1($value) {
return ''; // Clean phone1
}
@@ -154,10 +134,6 @@ class backup_anonymizer_helper {
return 0; // No picture
}
- public static function process_user_url($value) {
- return ''; // No url
- }
-
public static function process_user_description($value) {
return ''; // No user description
}
diff --git a/badges/criteria/award_criteria_profile.php b/badges/criteria/award_criteria_profile.php
index 6091b6281c2..9c02a19c6f4 100644
--- a/badges/criteria/award_criteria_profile.php
+++ b/badges/criteria/award_criteria_profile.php
@@ -51,8 +51,8 @@ class award_criteria_profile extends award_criteria {
$missing = array();
// Note: cannot use user_get_default_fields() here because it is not possible to decide which fields user can modify.
- $dfields = array('firstname', 'lastname', 'email', 'address', 'phone1', 'phone2', 'icq', 'skype', 'yahoo',
- 'aim', 'msn', 'department', 'institution', 'description', 'picture', 'city', 'url', 'country');
+ $dfields = array('firstname', 'lastname', 'email', 'address', 'phone1', 'phone2',
+ 'department', 'institution', 'description', 'picture', 'city', 'country');
$sql = "SELECT uf.id as fieldid, uf.name as name, ic.id as categoryid, ic.name as categoryname, uf.datatype
FROM {user_info_field} uf
diff --git a/badges/tests/badgeslib_test.php b/badges/tests/badgeslib_test.php
index 3231db1628f..b44d2f59a52 100644
--- a/badges/tests/badgeslib_test.php
+++ b/badges/tests/badgeslib_test.php
@@ -602,8 +602,8 @@ class badgeslib_test extends advanced_testcase {
$criteria_overall = award_criteria::build(array('criteriatype' => BADGE_CRITERIA_TYPE_OVERALL, 'badgeid' => $badge->id));
$criteria_overall->save(array('agg' => BADGE_CRITERIA_AGGREGATION_ANY));
$criteria_overall1 = award_criteria::build(array('criteriatype' => BADGE_CRITERIA_TYPE_PROFILE, 'badgeid' => $badge->id));
- $criteria_overall1->save(array('agg' => BADGE_CRITERIA_AGGREGATION_ALL, 'field_address' => 'address', 'field_aim' => 'aim',
- 'field_' . $customprofileid => $customprofileid));
+ $criteria_overall1->save(array('agg' => BADGE_CRITERIA_AGGREGATION_ALL, 'field_address' => 'address',
+ 'field_department' => 'department', 'field_' . $customprofileid => $customprofileid));
// Assert the badge will not be issued to the user as is.
$badge = new badge($this->coursebadge);
@@ -612,7 +612,7 @@ class badgeslib_test extends advanced_testcase {
// Set the required fields and make sure the badge got issued.
$this->user->address = 'Test address';
- $this->user->aim = '999999999';
+ $this->user->department = 'sillywalks';
$sink = $this->redirectEmails();
profile_save_data((object)array('id' => $this->user->id, 'profile_field_newfield' => 'X'));
user_update_user($this->user, false);
diff --git a/blocks/myprofile/classes/output/myprofile.php b/blocks/myprofile/classes/output/myprofile.php
index 714c9d01748..c604a37a67d 100644
--- a/blocks/myprofile/classes/output/myprofile.php
+++ b/blocks/myprofile/classes/output/myprofile.php
@@ -84,26 +84,6 @@ class myprofile implements renderable, templatable {
$data->useremail = obfuscate_mailto($USER->email, '');
}
- if (!empty($this->config->display_icq) && !empty($USER->icq)) {
- $data->usericq = s($USER->icq);
- }
-
- if (!empty($this->config->display_skype) && !empty($USER->skype)) {
- $data->userskype = s($USER->skype);
- }
-
- if (!empty($this->config->display_yahoo) && !empty($USER->yahoo)) {
- $data->useryahoo = s($USER->yahoo);
- }
-
- if (!empty($this->config->display_aim) && !empty($USER->aim)) {
- $data->useraim = s($USER->aim);
- }
-
- if (!empty($this->config->display_msn) && !empty($USER->msn)) {
- $data->usermsn = s($USER->msn);
- }
-
if (!empty($this->config->display_phone1) && !empty($USER->phone1)) {
$data->userphone1 = s($USER->phone1);
}
diff --git a/blocks/myprofile/edit_form.php b/blocks/myprofile/edit_form.php
index 0302647540c..6de49b23ddb 100644
--- a/blocks/myprofile/edit_form.php
+++ b/blocks/myprofile/edit_form.php
@@ -57,41 +57,6 @@ class block_myprofile_edit_form extends block_edit_form {
$mform->setDefault('config_display_email', '1');
}
- $mform->addElement('selectyesno', 'config_display_icq', get_string('display_icq', 'block_myprofile'));
- if (isset($this->block->config->display_icq)) {
- $mform->setDefault('config_display_icq', $this->block->config->display_icq);
- } else {
- $mform->setDefault('config_display_icq', '0');
- }
-
- $mform->addElement('selectyesno', 'config_display_skype', get_string('display_skype', 'block_myprofile'));
- if (isset($this->block->config->display_skype)) {
- $mform->setDefault('config_display_skype', $this->block->config->display_skype);
- } else {
- $mform->setDefault('config_display_skype', '0');
- }
-
- $mform->addElement('selectyesno', 'config_display_yahoo', get_string('display_yahoo', 'block_myprofile'));
- if (isset($this->block->config->display_yahoo)) {
- $mform->setDefault('config_display_yahoo', $this->block->config->display_yahoo);
- } else {
- $mform->setDefault('config_display_yahoo', '0');
- }
-
- $mform->addElement('selectyesno', 'config_display_aim', get_string('display_aim', 'block_myprofile'));
- if (isset($this->block->config->display_aim)) {
- $mform->setDefault('config_display_aim', $this->block->config->display_aim);
- } else {
- $mform->setDefault('config_display_aim', '0');
- }
-
- $mform->addElement('selectyesno', 'config_display_msn', get_string('display_msn', 'block_myprofile'));
- if (isset($this->block->config->display_msn)) {
- $mform->setDefault('config_display_msn', $this->block->config->display_msn);
- } else {
- $mform->setDefault('config_display_msn', '0');
- }
-
$mform->addElement('selectyesno', 'config_display_phone1', get_string('display_phone1', 'block_myprofile'));
if (isset($this->block->config->display_phone1)) {
$mform->setDefault('config_display_phone1', $this->block->config->display_phone1);
diff --git a/blocks/myprofile/lang/en/block_myprofile.php b/blocks/myprofile/lang/en/block_myprofile.php
index 5d886c2c078..e263d2c0846 100644
--- a/blocks/myprofile/lang/en/block_myprofile.php
+++ b/blocks/myprofile/lang/en/block_myprofile.php
@@ -28,11 +28,6 @@ $string['display_picture'] = 'Display picture';
$string['display_country'] = 'Display country';
$string['display_city'] = 'Display city';
$string['display_email'] = 'Display email';
-$string['display_icq'] = 'Display ICQ';
-$string['display_skype'] = 'Display Skype';
-$string['display_yahoo'] = 'Display Yahoo';
-$string['display_aim'] = 'Display AIM';
-$string['display_msn'] = 'Display MSN';
$string['display_phone1'] = 'Display phone';
$string['display_phone2'] = 'Display mobile phone';
$string['display_institution'] = 'Display institution';
@@ -46,3 +41,10 @@ $string['myprofile:myaddinstance'] = 'Add a new logged in user block to Dashboar
$string['myprofile_settings'] = 'Visible user information';
$string['pluginname'] = 'Logged in user';
$string['privacy:metadata'] = 'The Logged in user block only shows information about the logged in user and does not store data itself.';
+
+// Deprecated since Moodle 4.0.
+$string['display_icq'] = 'Display ICQ';
+$string['display_skype'] = 'Display Skype';
+$string['display_yahoo'] = 'Display Yahoo';
+$string['display_aim'] = 'Display AIM';
+$string['display_msn'] = 'Display MSN';
\ No newline at end of file
diff --git a/blocks/myprofile/templates/myprofile.mustache b/blocks/myprofile/templates/myprofile.mustache
index e132b0d95d9..d9505e7f373 100644
--- a/blocks/myprofile/templates/myprofile.mustache
+++ b/blocks/myprofile/templates/myprofile.mustache
@@ -33,11 +33,6 @@
* usercountry
* usercity
* useremail
- * usericq
- * userskype
- * useryahoo
- * useraim
- * usermsn
* userphone1
* userphone2
* userinstitution
@@ -54,11 +49,6 @@
"usercountry": "Australia",
"usercity": "Perth",
"useremail": "john.doe@example.com",
- "usericq": "12345",
- "userskype": "john.doe",
- "useryahoo": "12345",
- "useraim": "12345",
- "usermsn": "12345",
"userphone1": "123456789",
"userphone2": "123456789",
"userinstitution": "Institution",
@@ -98,36 +88,6 @@
{{{ useremail }}}
{{/useremail}}
- {{#usericq}}
-
{{#str}} phone1 {{/str}}:
diff --git a/blocks/myprofile/tests/behat/block_myprofile.feature b/blocks/myprofile/tests/behat/block_myprofile.feature
index 8bd076c80c8..8801de340d9 100644
--- a/blocks/myprofile/tests/behat/block_myprofile.feature
+++ b/blocks/myprofile/tests/behat/block_myprofile.feature
@@ -61,101 +61,6 @@ Feature: The logged in user block allows users to view their profile information
And I press "Save changes"
And I should see "teacher1@example.com" in the "Logged in user" "block"
- Scenario: Configure the logged in user block to show / hide the users ICQ
- Given the following "users" exist:
- | username | firstname | lastname | email | icq |
- | teacher1 | Teacher | One | teacher1@example.com | myicq |
- And I log in as "teacher1"
- And I press "Customise this page"
- When I add the "Logged in user" block
- And I configure the "Logged in user" block
- And I set the following fields to these values:
- | Display ICQ | No |
- And I press "Save changes"
- Then I should see "Teacher One" in the "Logged in user" "block"
- And I should not see "myicq" in the "Logged in user" "block"
- And I configure the "Logged in user" block
- And I set the following fields to these values:
- | Display ICQ | Yes |
- And I press "Save changes"
- And I should see "myicq" in the "Logged in user" "block"
-
- Scenario: Configure the logged in user block to show / hide the users Skype
- Given the following "users" exist:
- | username | firstname | lastname | email | skype |
- | teacher1 | Teacher | One | teacher1@example.com | myskype |
- And I log in as "teacher1"
- And I press "Customise this page"
- When I add the "Logged in user" block
- And I configure the "Logged in user" block
- And I set the following fields to these values:
- | Display Skype | No |
- And I press "Save changes"
- Then I should see "Teacher One" in the "Logged in user" "block"
- And I should not see "myskype" in the "Logged in user" "block"
- And I configure the "Logged in user" block
- And I set the following fields to these values:
- | Display Skype | Yes |
- And I press "Save changes"
- And I should see "myskype" in the "Logged in user" "block"
-
- Scenario: Configure the logged in user block to show / hide the users Yahoo
- Given the following "users" exist:
- | username | firstname | lastname | email | yahoo |
- | teacher1 | Teacher | One | teacher1@example.com | myyahoo |
- And I log in as "teacher1"
- And I press "Customise this page"
- When I add the "Logged in user" block
- And I configure the "Logged in user" block
- And I set the following fields to these values:
- | Display Yahoo | No |
- And I press "Save changes"
- Then I should see "Teacher One" in the "Logged in user" "block"
- And I should not see "myyahoo" in the "Logged in user" "block"
- And I configure the "Logged in user" block
- And I set the following fields to these values:
- | Display Yahoo | Yes |
- And I press "Save changes"
- And I should see "myyahoo" in the "Logged in user" "block"
-
- Scenario: Configure the logged in user block to show / hide the users AIM
- Given the following "users" exist:
- | username | firstname | lastname | email | aim |
- | teacher1 | Teacher | One | teacher1@example.com | myaim |
- And I log in as "teacher1"
- And I press "Customise this page"
- When I add the "Logged in user" block
- And I configure the "Logged in user" block
- And I set the following fields to these values:
- | Display AIM | No |
- And I press "Save changes"
- Then I should see "Teacher One" in the "Logged in user" "block"
- And I should not see "myaim" in the "Logged in user" "block"
- And I configure the "Logged in user" block
- And I set the following fields to these values:
- | Display AIM | Yes |
- And I press "Save changes"
- And I should see "myaim" in the "Logged in user" "block"
-
- Scenario: Configure the logged in user block to show / hide the users MSN
- Given the following "users" exist:
- | username | firstname | lastname | email | msn |
- | teacher1 | Teacher | One | teacher1@example.com | mymsn |
- And I log in as "teacher1"
- And I press "Customise this page"
- When I add the "Logged in user" block
- And I configure the "Logged in user" block
- And I set the following fields to these values:
- | Display MSN | No |
- And I press "Save changes"
- Then I should see "Teacher One" in the "Logged in user" "block"
- And I should not see "mymsn" in the "Logged in user" "block"
- And I configure the "Logged in user" block
- And I set the following fields to these values:
- | Display MSN | Yes |
- And I press "Save changes"
- And I should see "mymsn" in the "Logged in user" "block"
-
Scenario: Configure the logged in user block to show / hide the users phone
Given the following "users" exist:
| username | firstname | lastname | email | phone1 |
diff --git a/enrol/externallib.php b/enrol/externallib.php
index 116d1ff6d6a..0254bde5a4f 100644
--- a/enrol/externallib.php
+++ b/enrol/externallib.php
@@ -211,11 +211,6 @@ class core_enrol_external extends external_api {
'address' => new external_value(PARAM_MULTILANG, 'Postal address', VALUE_OPTIONAL),
'phone1' => new external_value(PARAM_NOTAGS, 'Phone 1', VALUE_OPTIONAL),
'phone2' => new external_value(PARAM_NOTAGS, 'Phone 2', VALUE_OPTIONAL),
- 'icq' => new external_value(PARAM_NOTAGS, 'icq number', VALUE_OPTIONAL),
- 'skype' => new external_value(PARAM_NOTAGS, 'skype id', VALUE_OPTIONAL),
- 'yahoo' => new external_value(PARAM_NOTAGS, 'yahoo id', VALUE_OPTIONAL),
- 'aim' => new external_value(PARAM_NOTAGS, 'aim id', VALUE_OPTIONAL),
- 'msn' => new external_value(PARAM_NOTAGS, 'msn number', VALUE_OPTIONAL),
'department' => new external_value(PARAM_TEXT, 'department', VALUE_OPTIONAL),
'institution' => new external_value(PARAM_TEXT, 'institution', VALUE_OPTIONAL),
'interests' => new external_value(PARAM_TEXT, 'user interests (separated by commas)', VALUE_OPTIONAL),
@@ -225,7 +220,6 @@ class core_enrol_external extends external_api {
'description' => new external_value(PARAM_RAW, 'User profile description', VALUE_OPTIONAL),
'descriptionformat' => new external_value(PARAM_INT, 'User profile description format', VALUE_OPTIONAL),
'city' => new external_value(PARAM_NOTAGS, 'Home city of the user', VALUE_OPTIONAL),
- 'url' => new external_value(PARAM_URL, 'URL of the user', VALUE_OPTIONAL),
'country' => new external_value(PARAM_ALPHA, 'Country code of the user, such as AU or CZ', VALUE_OPTIONAL),
'profileimageurlsmall' => new external_value(PARAM_URL, 'User image profile URL - small', VALUE_OPTIONAL),
'profileimageurl' => new external_value(PARAM_URL, 'User image profile URL - big', VALUE_OPTIONAL),
@@ -908,11 +902,6 @@ class core_enrol_external extends external_api {
'address' => new external_value(PARAM_TEXT, 'Postal address', VALUE_OPTIONAL),
'phone1' => new external_value(PARAM_NOTAGS, 'Phone 1', VALUE_OPTIONAL),
'phone2' => new external_value(PARAM_NOTAGS, 'Phone 2', VALUE_OPTIONAL),
- 'icq' => new external_value(PARAM_NOTAGS, 'icq number', VALUE_OPTIONAL),
- 'skype' => new external_value(PARAM_NOTAGS, 'skype id', VALUE_OPTIONAL),
- 'yahoo' => new external_value(PARAM_NOTAGS, 'yahoo id', VALUE_OPTIONAL),
- 'aim' => new external_value(PARAM_NOTAGS, 'aim id', VALUE_OPTIONAL),
- 'msn' => new external_value(PARAM_NOTAGS, 'msn number', VALUE_OPTIONAL),
'department' => new external_value(PARAM_TEXT, 'department', VALUE_OPTIONAL),
'institution' => new external_value(PARAM_TEXT, 'institution', VALUE_OPTIONAL),
'idnumber' => new external_value(PARAM_RAW, 'An arbitrary ID code number perhaps from the institution', VALUE_OPTIONAL),
@@ -923,7 +912,6 @@ class core_enrol_external extends external_api {
'description' => new external_value(PARAM_RAW, 'User profile description', VALUE_OPTIONAL),
'descriptionformat' => new external_format_value('description', VALUE_OPTIONAL),
'city' => new external_value(PARAM_NOTAGS, 'Home city of the user', VALUE_OPTIONAL),
- 'url' => new external_value(PARAM_URL, 'URL of the user', VALUE_OPTIONAL),
'country' => new external_value(PARAM_ALPHA, 'Home country code of the user, such as AU or CZ', VALUE_OPTIONAL),
'profileimageurlsmall' => new external_value(PARAM_URL, 'User image profile URL - small version', VALUE_OPTIONAL),
'profileimageurl' => new external_value(PARAM_URL, 'User image profile URL - big version', VALUE_OPTIONAL),
diff --git a/lang/en/deprecated.txt b/lang/en/deprecated.txt
index 96968e97656..ea3ac6bbae9 100644
--- a/lang/en/deprecated.txt
+++ b/lang/en/deprecated.txt
@@ -134,3 +134,18 @@ usernameoridoccurenceerror,core_webservice
addbackpack,core_badges
error:backpacknotavailable,core_badges
error:backpackproblem,core_badges
+privacy:metadata:mnet_external:aim,auth_mnet
+privacy:metadata:mnet_external:icq,auth_mnet
+privacy:metadata:mnet_external:msn,auth_mnet
+privacy:metadata:mnet_external:skype,auth_mnet
+privacy:metadata:mnet_external:url,auth_mnet
+privacy:metadata:mnet_external:yahoo,auth_mnet
+display_icq,block_myprofile
+display_skype,block_myprofile
+display_yahoo,block_myprofile
+display_aim,block_myprofile
+display_msn,block_myprofile
+aimid,core
+yahooid,core
+icqnumber,core
+msnid,core
diff --git a/lang/en/moodle.php b/lang/en/moodle.php
index 1090198974a..ea0e43b110f 100644
--- a/lang/en/moodle.php
+++ b/lang/en/moodle.php
@@ -123,7 +123,6 @@ $string['afterresource'] = 'After resource "{$a}"';
$string['aftersection'] = 'After section "{$a}"';
$string['again'] = 'again';
$string['agelocationverification'] = 'Age and location verification';
-$string['aimid'] = 'AIM ID';
$string['ajaxuse'] = 'AJAX and Javascript';
$string['all'] = 'All';
$string['allactions'] = 'All actions';
@@ -1049,7 +1048,6 @@ $string['eventcontentviewed'] = 'Content viewed';
$string['filter'] = 'Filter';
$string['filteroption'] = '{$a->criteria}: {$a->value}';
$string['filters'] = 'Filters';
-$string['icqnumber'] = 'ICQ number';
$string['icon'] = 'Icon';
$string['idnumber'] = 'ID number';
$string['idnumbercourse'] = 'Course ID number';
@@ -1356,7 +1354,6 @@ $string['moveselectedcategoriesto'] = 'Move selected categories to';
$string['moveselectedcoursesto'] = 'Move selected courses to...';
$string['movetoanotherfolder'] = 'Move to another folder';
$string['moveup'] = 'Move up';
-$string['msnid'] = 'MSN ID';
$string['mustconfirm'] = 'You need to confirm your account';
$string['mustchangepassword'] = 'The new password must be different than the current one';
$string['mycourses'] = 'My courses';
@@ -1972,7 +1969,6 @@ $string['skipped'] = 'Skipped';
$string['skiptocategorylisting'] = 'Skip to the category listings';
$string['skiptocourselisting'] = 'Skip to the course listings';
$string['skiptocoursedetails'] = 'Skip to the detailed course information';
-$string['skypeid'] = 'Skype ID';
$string['socialheadline'] = 'Social forum - latest topics';
$string['someallowguest'] = 'Some courses may allow guest access';
$string['someerrorswerefound'] = 'Some information was missing or incorrect. Look below for details.';
@@ -2298,7 +2294,6 @@ $string['writingmoduleinfo'] = 'Writing modules info';
$string['writingscalesinfo'] = 'Writing scales info';
$string['writinguserinfo'] = 'Writing users info';
$string['wrongpassword'] = 'Incorrect password for this username';
-$string['yahooid'] = 'Yahoo ID';
$string['year'] = 'year';
$string['years'] = 'years';
$string['yes'] = 'Yes';
@@ -2322,3 +2317,8 @@ $string['userfilterplaceholder'] = 'Search keyword or select filter';
// Deprecated since Moodle 3.11.
$string['hidepicture'] = 'Hide picture';
+$string['aimid'] = 'AIM ID';
+$string['yahooid'] = 'Yahoo ID';
+$string['skypeid'] = 'Skype ID';
+$string['icqnumber'] = 'ICQ number';
+$string['msnid'] = 'MSN ID';
diff --git a/lib/authlib.php b/lib/authlib.php
index 10be07e4e5e..b81c6ab4b5e 100644
--- a/lib/authlib.php
+++ b/lib/authlib.php
@@ -1200,8 +1200,6 @@ function display_auth_lock_options($settings, $auth, $userfields, $helptext, $ma
// limit for the setting name is 100.
$fieldnametoolong = true;
}
- } else if ($fieldname == 'url') {
- $fieldname = get_string('webpage');
} else {
$fieldname = get_string($fieldname);
}
diff --git a/lib/classes/oauth2/api.php b/lib/classes/oauth2/api.php
index 6219c8dc98c..448928887f8 100644
--- a/lib/classes/oauth2/api.php
+++ b/lib/classes/oauth2/api.php
@@ -40,6 +40,220 @@ use moodle_exception;
*/
class api {
+ /**
+ * Build a facebook ready OAuth 2 service.
+ * @return \core\oauth2\issuer
+ */
+ private static function init_facebook() {
+ // Facebook is a custom setup.
+ $record = (object) [
+ 'name' => 'Facebook',
+ 'image' => 'https://facebookbrand.com/wp-content/uploads/2016/05/flogo_rgb_hex-brc-site-250.png',
+ 'baseurl' => '',
+ 'loginscopes' => 'public_profile email',
+ 'loginscopesoffline' => 'public_profile email',
+ 'showonloginpage' => true,
+ 'servicetype' => 'facebook',
+ ];
+
+ $issuer = new issuer(0, $record);
+ return $issuer;
+ }
+
+ /**
+ * Create endpoints for facebook issuers.
+ * @param issuer $issuer issuer the endpoints should be created for.
+ * @return mixed
+ * @throws \coding_exception
+ * @throws \core\invalid_persistent_exception
+ */
+ private static function create_endpoints_for_facebook($issuer) {
+ // The Facebook API version.
+ $apiversion = '2.12';
+ // The Graph API URL.
+ $graphurl = 'https://graph.facebook.com/v' . $apiversion;
+ // User information fields that we want to fetch.
+ $infofields = [
+ 'id',
+ 'first_name',
+ 'last_name',
+ 'link',
+ 'picture.type(large)',
+ 'name',
+ 'email',
+ ];
+ $endpoints = [
+ 'authorization_endpoint' => sprintf('https://www.facebook.com/v%s/dialog/oauth', $apiversion),
+ 'token_endpoint' => $graphurl . '/oauth/access_token',
+ 'userinfo_endpoint' => $graphurl . '/me?fields=' . implode(',', $infofields)
+ ];
+
+ foreach ($endpoints as $name => $url) {
+ $record = (object) [
+ 'issuerid' => $issuer->get('id'),
+ 'name' => $name,
+ 'url' => $url
+ ];
+ $endpoint = new endpoint(0, $record);
+ $endpoint->create();
+ }
+
+ // Create the field mappings.
+ $mapping = [
+ 'name' => 'alternatename',
+ 'last_name' => 'lastname',
+ 'email' => 'email',
+ 'first_name' => 'firstname',
+ 'picture-data-url' => 'picture',
+ ];
+ foreach ($mapping as $external => $internal) {
+ $record = (object) [
+ 'issuerid' => $issuer->get('id'),
+ 'externalfield' => $external,
+ 'internalfield' => $internal
+ ];
+ $userfieldmapping = new user_field_mapping(0, $record);
+ $userfieldmapping->create();
+ }
+ return $issuer;
+ }
+
+ /**
+ * Build a microsoft ready OAuth 2 service.
+ * @return \core\oauth2\issuer
+ */
+ private static function init_microsoft() {
+ // Microsoft is a custom setup.
+ $record = (object) [
+ 'name' => 'Microsoft',
+ 'image' => 'https://www.microsoft.com/favicon.ico',
+ 'baseurl' => '',
+ 'loginscopes' => 'openid profile email user.read',
+ 'loginscopesoffline' => 'openid profile email user.read offline_access',
+ 'showonloginpage' => true,
+ 'servicetype' => 'microsoft',
+ ];
+
+ $issuer = new issuer(0, $record);
+ return $issuer;
+ }
+
+ /**
+ * Create endpoints for microsoft issuers.
+ * @param issuer $issuer issuer the endpoints should be created for.
+ * @return mixed
+ * @throws \coding_exception
+ * @throws \core\invalid_persistent_exception
+ */
+ private static function create_endpoints_for_microsoft($issuer) {
+
+ $endpoints = [
+ 'authorization_endpoint' => 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize',
+ 'token_endpoint' => 'https://login.microsoftonline.com/common/oauth2/v2.0/token',
+ 'userinfo_endpoint' => 'https://graph.microsoft.com/v1.0/me/',
+ 'userpicture_endpoint' => 'https://graph.microsoft.com/v1.0/me/photo/$value',
+ ];
+
+ foreach ($endpoints as $name => $url) {
+ $record = (object) [
+ 'issuerid' => $issuer->get('id'),
+ 'name' => $name,
+ 'url' => $url
+ ];
+ $endpoint = new endpoint(0, $record);
+ $endpoint->create();
+ }
+
+ // Create the field mappings.
+ $mapping = [
+ 'givenName' => 'firstname',
+ 'surname' => 'lastname',
+ 'userPrincipalName' => 'email',
+ 'displayName' => 'alternatename',
+ 'officeLocation' => 'address',
+ 'mobilePhone' => 'phone1',
+ 'preferredLanguage' => 'lang'
+ ];
+ foreach ($mapping as $external => $internal) {
+ $record = (object) [
+ 'issuerid' => $issuer->get('id'),
+ 'externalfield' => $external,
+ 'internalfield' => $internal
+ ];
+ $userfieldmapping = new user_field_mapping(0, $record);
+ $userfieldmapping->create();
+ }
+ return $issuer;
+ }
+
+ /**
+ * Build a nextcloud ready OAuth 2 service.
+ * @return \core\oauth2\issuer
+ */
+ private static function init_nextcloud() {
+ // Nextcloud has a custom baseurl. Thus, the creation of endpoints has to be done later.
+ $record = (object) [
+ 'name' => 'Nextcloud',
+ 'image' => 'https://nextcloud.com/wp-content/themes/next/assets/img/common/favicon.png?x16328',
+ 'basicauth' => 1,
+ 'servicetype' => 'nextcloud',
+ ];
+
+ $issuer = new issuer(0, $record);
+
+ return $issuer;
+ }
+
+ /**
+ * Create endpoints for nextcloud issuers.
+ * @param issuer $issuer issuer the endpoints should be created for.
+ * @return mixed
+ * @throws \coding_exception
+ * @throws \core\invalid_persistent_exception
+ */
+ private static function create_endpoints_for_nextcloud($issuer) {
+ $baseurl = $issuer->get('baseurl');
+ // Add trailing slash to baseurl, if needed.
+ if (substr($baseurl, -1) !== '/') {
+ $baseurl .= '/';
+ }
+
+ $endpoints = [
+ // Baseurl will be prepended later.
+ 'authorization_endpoint' => 'index.php/apps/oauth2/authorize',
+ 'token_endpoint' => 'index.php/apps/oauth2/api/v1/token',
+ 'userinfo_endpoint' => 'ocs/v2.php/cloud/user?format=json',
+ 'webdav_endpoint' => 'remote.php/webdav/',
+ 'ocs_endpoint' => 'ocs/v1.php/apps/files_sharing/api/v1/shares',
+ ];
+
+ foreach ($endpoints as $name => $url) {
+ $record = (object) [
+ 'issuerid' => $issuer->get('id'),
+ 'name' => $name,
+ 'url' => $baseurl . $url,
+ ];
+ $endpoint = new \core\oauth2\endpoint(0, $record);
+ $endpoint->create();
+ }
+
+ // Create the field mappings.
+ $mapping = [
+ 'ocs-data-email' => 'email',
+ 'ocs-data-id' => 'username',
+ ];
+ foreach ($mapping as $external => $internal) {
+ $record = (object) [
+ 'issuerid' => $issuer->get('id'),
+ 'externalfield' => $external,
+ 'internalfield' => $internal
+ ];
+ $userfieldmapping = new \core\oauth2\user_field_mapping(0, $record);
+ $userfieldmapping->create();
+ }
+ return $issuer;
+ }
+
/**
* Initializes a record for one of the standard issuers to be displayed in the settings.
* The issuer is not yet created in the database.
diff --git a/lib/classes/oauth2/discovery/openidconnect.php b/lib/classes/oauth2/discovery/openidconnect.php
index f1c58631427..89a475327e3 100644
--- a/lib/classes/oauth2/discovery/openidconnect.php
+++ b/lib/classes/oauth2/discovery/openidconnect.php
@@ -93,7 +93,6 @@ class openidconnect extends base_definition {
'middle_name' => 'middlename',
'family_name' => 'lastname',
'email' => 'email',
- 'website' => 'url',
'nickname' => 'alternatename',
'picture' => 'picture',
'address' => 'address',
diff --git a/lib/classes/oauth2/service/facebook.php b/lib/classes/oauth2/service/facebook.php
index 92ec1f513d2..9e1e49324bd 100644
--- a/lib/classes/oauth2/service/facebook.php
+++ b/lib/classes/oauth2/service/facebook.php
@@ -66,7 +66,6 @@ class facebook extends openidconnect implements issuer_interface {
'id',
'first_name',
'last_name',
- 'link',
'picture.type(large)',
'name',
'email',
@@ -94,7 +93,6 @@ class facebook extends openidconnect implements issuer_interface {
'email' => 'email',
'first_name' => 'firstname',
'picture-data-url' => 'picture',
- 'link' => 'url',
];
foreach ($mapping as $external => $internal) {
$record = (object) [
diff --git a/lib/classes/user.php b/lib/classes/user.php
index 0cb5e4f8a7d..c6dddc67a6a 100644
--- a/lib/classes/user.php
+++ b/lib/classes/user.php
@@ -69,7 +69,6 @@ class core_user {
'country',
'lang',
'description',
- 'url',
'idnumber',
'institution',
'department',
@@ -669,11 +668,6 @@ class core_user {
$fields['surname'] = array('type' => PARAM_NOTAGS, 'null' => NULL_NOT_ALLOWED);
$fields['email'] = array('type' => PARAM_RAW_TRIMMED, 'null' => NULL_NOT_ALLOWED);
$fields['emailstop'] = array('type' => PARAM_INT, 'null' => NULL_NOT_ALLOWED, 'default' => 0);
- $fields['icq'] = array('type' => PARAM_NOTAGS, 'null' => NULL_NOT_ALLOWED);
- $fields['skype'] = array('type' => PARAM_NOTAGS, 'null' => NULL_ALLOWED);
- $fields['aim'] = array('type' => PARAM_NOTAGS, 'null' => NULL_NOT_ALLOWED);
- $fields['yahoo'] = array('type' => PARAM_NOTAGS, 'null' => NULL_NOT_ALLOWED);
- $fields['msn'] = array('type' => PARAM_NOTAGS, 'null' => NULL_NOT_ALLOWED);
$fields['phone1'] = array('type' => PARAM_NOTAGS, 'null' => NULL_NOT_ALLOWED);
$fields['phone2'] = array('type' => PARAM_NOTAGS, 'null' => NULL_NOT_ALLOWED);
$fields['institution'] = array('type' => PARAM_TEXT, 'null' => NULL_NOT_ALLOWED);
@@ -698,7 +692,6 @@ class core_user {
$fields['lastip'] = array('type' => PARAM_NOTAGS, 'null' => NULL_NOT_ALLOWED);
$fields['secret'] = array('type' => PARAM_ALPHANUM, 'null' => NULL_NOT_ALLOWED);
$fields['picture'] = array('type' => PARAM_INT, 'null' => NULL_NOT_ALLOWED);
- $fields['url'] = array('type' => PARAM_URL, 'null' => NULL_NOT_ALLOWED);
$fields['description'] = array('type' => PARAM_RAW, 'null' => NULL_ALLOWED);
$fields['descriptionformat'] = array('type' => PARAM_INT, 'null' => NULL_NOT_ALLOWED);
$fields['mailformat'] = array('type' => PARAM_INT, 'null' => NULL_NOT_ALLOWED,
diff --git a/lib/db/install.xml b/lib/db/install.xml
index fdeba8596f2..daaa8339731 100644
--- a/lib/db/install.xml
+++ b/lib/db/install.xml
@@ -837,11 +837,6 @@
-
-
-
-
-
@@ -860,7 +855,6 @@
-
diff --git a/lib/db/upgrade.php b/lib/db/upgrade.php
index cb43328e0e0..ecdd8a8b833 100644
--- a/lib/db/upgrade.php
+++ b/lib/db/upgrade.php
@@ -2560,5 +2560,28 @@ function xmldb_main_upgrade($oldversion) {
upgrade_main_savepoint(true, 2021052500.78);
}
+ if ($oldversion < 2021052500.80) {
+ require_once($CFG->dirroot . '/user/profile/field/social/upgradelib.php');
+ $table = new xmldb_table('user');
+ $tablecolumns = ['icq', 'skype', 'aim', 'yahoo', 'msn', 'url'];
+
+ foreach ($tablecolumns as $column) {
+ $field = new xmldb_field($column);
+ if ($dbman->field_exists($table, $field)) {
+ user_profile_social_moveto_profilefield($column);
+ $dbman->drop_field($table, $field);
+ }
+ }
+
+ // Update all module availability if it relies on the old user fields.
+ user_profile_social_update_module_availability();
+
+ // Remove field mapping for oauth2.
+ $DB->delete_records('oauth2_user_field_mapping', array('internalfield' => 'url'));
+
+ // Main savepoint reached.
+ upgrade_main_savepoint(true, 2021052500.80);
+ }
+
return true;
}
diff --git a/lib/moodlelib.php b/lib/moodlelib.php
index 6fc92dd9458..b6e9e2f2e63 100644
--- a/lib/moodlelib.php
+++ b/lib/moodlelib.php
@@ -4011,7 +4011,6 @@ function truncate_userinfo(array $info) {
'firstname' => 100,
'lastname' => 100,
'email' => 100,
- 'icq' => 15,
'phone1' => 20,
'phone2' => 20,
'institution' => 255,
@@ -4019,7 +4018,6 @@ function truncate_userinfo(array $info) {
'address' => 255,
'city' => 120,
'country' => 2,
- 'url' => 255,
);
// Apply where needed.
diff --git a/lib/myprofilelib.php b/lib/myprofilelib.php
index da370c899d6..bed91290310 100644
--- a/lib/myprofilelib.php
+++ b/lib/myprofilelib.php
@@ -219,17 +219,6 @@ function core_myprofile_navigation(core_user\output\myprofile\tree $tree, $user,
$tree->add_node($node);
}
- if ($user->url && !isset($hiddenfields['webpage'])) {
- $url = $user->url;
- if (strpos($user->url, '://') === false) {
- $url = 'http://'. $url;
- }
- $webpageurl = new moodle_url($url);
- $node = new core_user\output\myprofile\node('contact', 'webpage', get_string('webpage'), null, null,
- html_writer::link($url, $webpageurl));
- $tree->add_node($node);
- }
-
// Printing tagged interests. We want this only for full profile.
if (empty($course) && ($interests = core_tag_tag::get_item_tags('core', 'user', $user->id))) {
$node = new core_user\output\myprofile\node('contact', 'interests', get_string('interests'), null, null,
@@ -334,38 +323,6 @@ function core_myprofile_navigation(core_user\output\myprofile\tree $tree, $user,
}
}
- if ($user->icq && !isset($hiddenfields['icqnumber'])) {
- $imurl = new moodle_url('https://web.icq.com/wwp', array('uin' => $user->icq) );
- $iconurl = new moodle_url('https://web.icq.com/whitepages/online', array('icq' => $user->icq, 'img' => '5'));
- $statusicon = html_writer::tag('img', '',
- array('src' => $iconurl, 'class' => 'icon icon-post', 'alt' => get_string('status')));
- $node = new core_user\output\myprofile\node('contact', 'icqnumber', get_string('icqnumber'), null, null,
- html_writer::link($imurl, s($user->icq) . $statusicon));
- $tree->add_node($node);
- }
-
- if ($user->skype && !isset($hiddenfields['skypeid'])) {
- $imurl = 'skype:' . urlencode($user->skype) . '?call';
- $node = new core_user\output\myprofile\node('contact', 'skypeid', get_string('skypeid'), null, null,
- html_writer::link($imurl, s($user->skype)));
- $tree->add_node($node);
- }
- if ($user->yahoo && !isset($hiddenfields['yahooid'])) {
- $node = new core_user\output\myprofile\node('contact', 'yahooid', get_string('yahooid'), null, null,
- s($user->yahoo));
- $tree->add_node($node);
- }
- if ($user->aim && !isset($hiddenfields['aimid'])) {
- $node = new core_user\output\myprofile\node('contact', 'aimid', get_string('aimid'), null, null,
- s($user->aim));
- $tree->add_node($node);
- }
- if ($user->msn && !isset($hiddenfields['msnid'])) {
- $node = new core_user\output\myprofile\node('contact', 'msnid', get_string('msnid'), null, null,
- s($user->msn));
- $tree->add_node($node);
- }
-
$categories = profile_get_user_fields_with_data_by_category($user->id);
foreach ($categories as $categoryid => $fields) {
foreach ($fields as $formfield) {
diff --git a/lib/tests/datalib_test.php b/lib/tests/datalib_test.php
index 9f786b6dd38..b81ddefdab6 100644
--- a/lib/tests/datalib_test.php
+++ b/lib/tests/datalib_test.php
@@ -60,17 +60,11 @@ class core_datalib_testcase extends advanced_testcase {
'address' => '2 Test Street Perth 6000 WA',
'phone1' => '01010101010',
'phone2' => '02020203',
- 'icq' => 'testuser1',
- 'skype' => 'testuser1',
- 'yahoo' => 'testuser1',
- 'aim' => 'testuser1',
- 'msn' => 'testuser1',
'department' => 'Department of user 1',
'institution' => 'Institution of user 1',
'description' => 'This is a description for user 1',
'descriptionformat' => FORMAT_MOODLE,
'city' => 'Perth',
- 'url' => 'http://moodle.org',
'country' => 'AU'
);
$user1 = self::getDataGenerator()->create_user($user1);
@@ -83,17 +77,11 @@ class core_datalib_testcase extends advanced_testcase {
'address' => '222 Test Street Perth 6000 WA',
'phone1' => '01010101010',
'phone2' => '02020203',
- 'icq' => 'testuser1',
- 'skype' => 'testuser1',
- 'yahoo' => 'testuser1',
- 'aim' => 'testuser1',
- 'msn' => 'testuser1',
'department' => 'Department of user 2',
'institution' => 'Institution of user 2',
'description' => 'This is a description for user 2',
'descriptionformat' => FORMAT_MOODLE,
'city' => 'Perth',
- 'url' => 'http://moodle.org',
'country' => 'AU'
);
$user2 = self::getDataGenerator()->create_user($user2);
diff --git a/lib/tests/myprofilelib_test.php b/lib/tests/myprofilelib_test.php
index 20476c0d695..47cab7d4c37 100644
--- a/lib/tests/myprofilelib_test.php
+++ b/lib/tests/myprofilelib_test.php
@@ -169,7 +169,7 @@ class core_myprofilelib_testcase extends advanced_testcase {
global $CFG;
// User contact fields.
- set_config("hiddenuserfields", "country,city,webpage,icqnumber,skypeid,yahooid,aimid,msnid");
+ set_config("hiddenuserfields", "country,city");
set_config("showuseridentity", "email,address,phone1,phone2,institution,department,idnumber");
$hiddenfields = explode(',', $CFG->hiddenuserfields);
$identityfields = explode(',', $CFG->showuseridentity);
@@ -180,12 +180,6 @@ class core_myprofilelib_testcase extends advanced_testcase {
$fields = array(
'country' => 'AU',
'city' => 'Silent hill',
- 'url' => 'Ghosts',
- 'icq' => 'Wth is ICQ?',
- 'skype' => 'derp',
- 'yahoo' => 'are you living in the 90\'s?',
- 'aim' => 'are you for real?',
- 'msn' => '...',
'email' => 'Rulelikeaboss@example.com',
'address' => 'Didn\'t I mention silent hill already ?',
'phone1' => '123',
diff --git a/mod/forum/classes/task/send_user_notifications.php b/mod/forum/classes/task/send_user_notifications.php
index d177f6e8a32..1e5efff06db 100644
--- a/mod/forum/classes/task/send_user_notifications.php
+++ b/mod/forum/classes/task/send_user_notifications.php
@@ -548,7 +548,6 @@ class send_user_notifications extends \core\task\adhoc_task {
unset($user->department);
unset($user->address);
unset($user->city);
- unset($user->url);
unset($user->currentlogin);
unset($user->description);
unset($user->descriptionformat);
diff --git a/mod/forum/deprecatedlib.php b/mod/forum/deprecatedlib.php
index 29f2dc35be6..30345f69c6f 100644
--- a/mod/forum/deprecatedlib.php
+++ b/mod/forum/deprecatedlib.php
@@ -392,7 +392,6 @@ function forum_cron_minimise_user_record(stdClass $user) {
unset($user->department);
unset($user->address);
unset($user->city);
- unset($user->url);
unset($user->currentlogin);
unset($user->description);
unset($user->descriptionformat);
diff --git a/mod/url/locallib.php b/mod/url/locallib.php
index 8ca4fd26c15..8209620868a 100644
--- a/mod/url/locallib.php
+++ b/mod/url/locallib.php
@@ -446,7 +446,6 @@ function url_get_variable_options($config) {
'userlastname' => get_string('lastname'),
'userfullname' => get_string('fullnameuser'),
'useremail' => get_string('email'),
- 'usericq' => get_string('icqnumber'),
'userphone1' => get_string('phone1'),
'userphone2' => get_string('phone2'),
'userinstitution' => get_string('institution'),
@@ -454,7 +453,6 @@ function url_get_variable_options($config) {
'useraddress' => get_string('address'),
'usercity' => get_string('city'),
'usertimezone' => get_string('timezone'),
- 'userurl' => get_string('webpage'),
);
if ($config->rolesinparams) {
@@ -509,7 +507,6 @@ function url_get_variable_values($url, $cm, $course, $config) {
$values['userlastname'] = $USER->lastname;
$values['userfullname'] = fullname($USER);
$values['useremail'] = $USER->email;
- $values['usericq'] = $USER->icq;
$values['userphone1'] = $USER->phone1;
$values['userphone2'] = $USER->phone2;
$values['userinstitution'] = $USER->institution;
@@ -518,7 +515,6 @@ function url_get_variable_values($url, $cm, $course, $config) {
$values['usercity'] = $USER->city;
$now = new DateTime('now', core_date::get_user_timezone_object());
$values['usertimezone'] = $now->getOffset() / 3600.0; // Value in hours for BC.
- $values['userurl'] = $USER->url;
}
// weak imitation of Single-Sign-On, for backwards compatibility only
diff --git a/user/classes/analytics/indicator/user_profile_set.php b/user/classes/analytics/indicator/user_profile_set.php
index 20639ac8417..eee75d3df7c 100644
--- a/user/classes/analytics/indicator/user_profile_set.php
+++ b/user/classes/analytics/indicator/user_profile_set.php
@@ -90,7 +90,7 @@ class user_profile_set extends \core_analytics\local\indicator\linear {
}
// 0.2 for any of the following fields being set (some of them may even be compulsory or have a default).
- $fields = array('institution', 'department', 'address', 'city', 'country', 'url');
+ $fields = array('institution', 'department', 'address', 'city', 'country');
foreach ($fields as $fieldname) {
if ($user->{$fieldname} != '') {
$calculatedvalue += 0.2;
diff --git a/user/classes/privacy/provider.php b/user/classes/privacy/provider.php
index 74b28a8bc3a..228142745e2 100644
--- a/user/classes/privacy/provider.php
+++ b/user/classes/privacy/provider.php
@@ -68,11 +68,6 @@ class provider implements
'lastname' => 'privacy:metadata:lastname',
'email' => 'privacy:metadata:email',
'emailstop' => 'privacy:metadata:emailstop',
- 'icq' => 'privacy:metadata:icq',
- 'skype' => 'privacy:metadata:skype',
- 'yahoo' => 'privacy:metadata:yahoo',
- 'aim' => 'privacy:metadata:aim',
- 'msn' => 'privacy:metadata:msn',
'phone1' => 'privacy:metadata:phone',
'phone2' => 'privacy:metadata:phone',
'institution' => 'privacy:metadata:institution',
@@ -91,7 +86,6 @@ class provider implements
'lastip' => 'privacy:metadata:lastip',
'secret' => 'privacy:metadata:secret',
'picture' => 'privacy:metadata:picture',
- 'url' => 'privacy:metadata:url',
'description' => 'privacy:metadata:description',
'maildigest' => 'privacy:metadata:maildigest',
'maildisplay' => 'privacy:metadata:maildisplay',
@@ -309,11 +303,6 @@ class provider implements
$user->deleted = 1;
$user->idnumber = '';
$user->emailstop = 0;
- $user->icq = '';
- $user->skype = '';
- $user->yahoo = '';
- $user->aim = '';
- $user->msn = '';
$user->phone1 = '';
$user->phone2 = '';
$user->institution = '';
@@ -332,7 +321,6 @@ class provider implements
$user->lastip = 0;
$user->secret = '';
$user->picture = '';
- $user->url = '';
$user->description = '';
$user->descriptionformat = 0;
$user->mailformat = 0;
@@ -370,11 +358,6 @@ class provider implements
'lastname' => format_string($user->lastname, true, ['context' => $context]),
'email' => $user->email,
'emailstop' => transform::yesno($user->emailstop),
- 'icq' => format_string($user->icq, true, ['context' => $context]),
- 'skype' => format_string($user->skype, true, ['context' => $context]),
- 'yahoo' => format_string($user->yahoo, true, ['context' => $context]),
- 'aim' => format_string($user->aim, true, ['context' => $context]),
- 'msn' => format_string($user->msn, true, ['context' => $context]),
'phone1' => format_string($user->phone1, true, ['context' => $context]),
'phone2' => format_string($user->phone2, true, ['context' => $context]),
'institution' => format_string($user->institution, true, ['context' => $context]),
@@ -393,7 +376,6 @@ class provider implements
'lastip' => $user->lastip,
'secret' => $user->secret,
'picture' => $user->picture,
- 'url' => $user->url,
'description' => format_text($user->description, $user->descriptionformat, ['context' => $context]),
'maildigest' => transform::yesno($user->maildigest),
'maildisplay' => $user->maildisplay,
diff --git a/user/editlib.php b/user/editlib.php
index 8d407d5859b..06940bf8ab0 100644
--- a/user/editlib.php
+++ b/user/editlib.php
@@ -394,29 +394,6 @@ function useredit_shared_definition(&$mform, $editoroptions, $filemanageroptions
// Moodle optional fields.
$mform->addElement('header', 'moodle_optional', get_string('optional', 'form'));
- $mform->addElement('text', 'url', get_string('webpage'), 'maxlength="255" size="50"');
- $mform->setType('url', core_user::get_property_type('url'));
-
- $mform->addElement('text', 'icq', get_string('icqnumber'), 'maxlength="15" size="25"');
- $mform->setType('icq', core_user::get_property_type('icq'));
- $mform->setForceLtr('icq');
-
- $mform->addElement('text', 'skype', get_string('skypeid'), 'maxlength="50" size="25"');
- $mform->setType('skype', core_user::get_property_type('skype'));
- $mform->setForceLtr('skype');
-
- $mform->addElement('text', 'aim', get_string('aimid'), 'maxlength="50" size="25"');
- $mform->setType('aim', core_user::get_property_type('aim'));
- $mform->setForceLtr('aim');
-
- $mform->addElement('text', 'yahoo', get_string('yahooid'), 'maxlength="50" size="25"');
- $mform->setType('yahoo', core_user::get_property_type('yahoo'));
- $mform->setForceLtr('yahoo');
-
- $mform->addElement('text', 'msn', get_string('msnid'), 'maxlength="50" size="25"');
- $mform->setType('msn', core_user::get_property_type('msn'));
- $mform->setForceLtr('msn');
-
$mform->addElement('text', 'idnumber', get_string('idnumber'), 'maxlength="255" size="25"');
$mform->setType('idnumber', core_user::get_property_type('idnumber'));
diff --git a/user/externallib.php b/user/externallib.php
index 90c9bd423db..86381b25fea 100644
--- a/user/externallib.php
+++ b/user/externallib.php
@@ -79,12 +79,6 @@ class core_user_external extends external_api {
// Interests.
'interests' => new external_value(PARAM_TEXT, 'User interests (separated by commas)', VALUE_OPTIONAL),
// Optional.
- 'url' => new external_value(core_user::get_property_type('url'), 'User web page', VALUE_OPTIONAL),
- 'icq' => new external_value(core_user::get_property_type('icq'), 'ICQ number', VALUE_OPTIONAL),
- 'skype' => new external_value(core_user::get_property_type('skype'), 'Skype ID', VALUE_OPTIONAL),
- 'aim' => new external_value(core_user::get_property_type('aim'), 'AIM ID', VALUE_OPTIONAL),
- 'yahoo' => new external_value(core_user::get_property_type('yahoo'), 'Yahoo ID', VALUE_OPTIONAL),
- 'msn' => new external_value(core_user::get_property_type('msn'), 'MSN ID', VALUE_OPTIONAL),
'idnumber' => new external_value(core_user::get_property_type('idnumber'),
'An arbitrary ID code number perhaps from the institution', VALUE_DEFAULT, ''),
'institution' => new external_value(core_user::get_property_type('institution'), 'institution', VALUE_OPTIONAL),
@@ -503,12 +497,6 @@ class core_user_external extends external_api {
// Interests.
'interests' => new external_value(PARAM_TEXT, 'User interests (separated by commas)', VALUE_OPTIONAL),
// Optional.
- 'url' => new external_value(core_user::get_property_type('url'), 'User web page', VALUE_OPTIONAL),
- 'icq' => new external_value(core_user::get_property_type('icq'), 'ICQ number', VALUE_OPTIONAL),
- 'skype' => new external_value(core_user::get_property_type('skype'), 'Skype ID', VALUE_OPTIONAL),
- 'aim' => new external_value(core_user::get_property_type('aim'), 'AIM ID', VALUE_OPTIONAL),
- 'yahoo' => new external_value(core_user::get_property_type('yahoo'), 'Yahoo ID', VALUE_OPTIONAL),
- 'msn' => new external_value(core_user::get_property_type('msn'), 'MSN ID', VALUE_OPTIONAL),
'idnumber' => new external_value(core_user::get_property_type('idnumber'),
'An arbitrary ID code number perhaps from the institution', VALUE_OPTIONAL),
'institution' => new external_value(core_user::get_property_type('institution'), 'Institution', VALUE_OPTIONAL),
@@ -1093,11 +1081,6 @@ class core_user_external extends external_api {
'address' => new external_value(core_user::get_property_type('address'), 'Postal address', VALUE_OPTIONAL),
'phone1' => new external_value(core_user::get_property_type('phone1'), 'Phone 1', VALUE_OPTIONAL),
'phone2' => new external_value(core_user::get_property_type('phone2'), 'Phone 2', VALUE_OPTIONAL),
- 'icq' => new external_value(core_user::get_property_type('icq'), 'icq number', VALUE_OPTIONAL),
- 'skype' => new external_value(core_user::get_property_type('skype'), 'skype id', VALUE_OPTIONAL),
- 'yahoo' => new external_value(core_user::get_property_type('yahoo'), 'yahoo id', VALUE_OPTIONAL),
- 'aim' => new external_value(core_user::get_property_type('aim'), 'aim id', VALUE_OPTIONAL),
- 'msn' => new external_value(core_user::get_property_type('msn'), 'msn number', VALUE_OPTIONAL),
'department' => new external_value(core_user::get_property_type('department'), 'department', VALUE_OPTIONAL),
'institution' => new external_value(core_user::get_property_type('institution'), 'institution', VALUE_OPTIONAL),
'idnumber' => new external_value(core_user::get_property_type('idnumber'), 'An arbitrary ID code number perhaps from the institution', VALUE_OPTIONAL),
@@ -1115,7 +1098,6 @@ class core_user_external extends external_api {
'description' => new external_value(core_user::get_property_type('description'), 'User profile description', VALUE_OPTIONAL),
'descriptionformat' => new external_format_value(core_user::get_property_type('descriptionformat'), VALUE_OPTIONAL),
'city' => new external_value(core_user::get_property_type('city'), 'Home city of the user', VALUE_OPTIONAL),
- 'url' => new external_value(core_user::get_property_type('url'), 'URL of the user', VALUE_OPTIONAL),
'country' => new external_value(core_user::get_property_type('country'), 'Home country code of the user, such as AU or CZ', VALUE_OPTIONAL),
'profileimageurlsmall' => new external_value(PARAM_URL, 'User image profile URL - small version'),
'profileimageurl' => new external_value(PARAM_URL, 'User image profile URL - big version'),
diff --git a/user/lib.php b/user/lib.php
index 3809b8170a3..6332648c790 100644
--- a/user/lib.php
+++ b/user/lib.php
@@ -242,10 +242,10 @@ function user_get_users_by_id($userids) {
*/
function user_get_default_fields() {
return array( 'id', 'username', 'fullname', 'firstname', 'lastname', 'email',
- 'address', 'phone1', 'phone2', 'icq', 'skype', 'yahoo', 'aim', 'msn', 'department',
+ 'address', 'phone1', 'phone2', 'department',
'institution', 'interests', 'firstaccess', 'lastaccess', 'auth', 'confirmed',
'idnumber', 'lang', 'theme', 'timezone', 'mailformat', 'description', 'descriptionformat',
- 'city', 'url', 'country', 'profileimageurlsmall', 'profileimageurl', 'customfields',
+ 'city', 'country', 'profileimageurlsmall', 'profileimageurl', 'customfields',
'groups', 'roles', 'preferences', 'enrolledcourses', 'suspended', 'lastcourseaccess'
);
}
@@ -429,31 +429,6 @@ function user_get_user_details($user, $course = null, array $userfields = array(
$userdetails['city'] = $user->city;
}
- if (in_array('url', $userfields) && $user->url && (!isset($hiddenfields['webpage']) or $isadmin)) {
- $url = $user->url;
- if (strpos($user->url, '://') === false) {
- $url = 'http://'. $url;
- }
- $user->url = clean_param($user->url, PARAM_URL);
- $userdetails['url'] = $user->url;
- }
-
- if (in_array('icq', $userfields) && $user->icq && (!isset($hiddenfields['icqnumber']) or $isadmin)) {
- $userdetails['icq'] = $user->icq;
- }
-
- if (in_array('skype', $userfields) && $user->skype && (!isset($hiddenfields['skypeid']) or $isadmin)) {
- $userdetails['skype'] = $user->skype;
- }
- if (in_array('yahoo', $userfields) && $user->yahoo && (!isset($hiddenfields['yahooid']) or $isadmin)) {
- $userdetails['yahoo'] = $user->yahoo;
- }
- if (in_array('aim', $userfields) && $user->aim && (!isset($hiddenfields['aimid']) or $isadmin)) {
- $userdetails['aim'] = $user->aim;
- }
- if (in_array('msn', $userfields) && $user->msn && (!isset($hiddenfields['msnid']) or $isadmin)) {
- $userdetails['msn'] = $user->msn;
- }
if (in_array('suspended', $userfields) && (!isset($hiddenfields['suspended']) or $isadmin)) {
$userdetails['suspended'] = (bool)$user->suspended;
}
diff --git a/user/profile/field/social/classes/helper.php b/user/profile/field/social/classes/helper.php
new file mode 100644
index 00000000000..677e2eb2025
--- /dev/null
+++ b/user/profile/field/social/classes/helper.php
@@ -0,0 +1,74 @@
+.
+
+/**
+ * Contains class profilefield_social\networks
+ *
+ * @package profilefield_social
+ * @copyright 2020 Bas Brands
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace profilefield_social;
+
+/**
+ * helper class for social profile fields.
+ *
+ * @copyright 2020 Bas Brands
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class helper {
+
+ /**
+ * Get the available social networks
+ *
+ * @return array list of social networks.
+ */
+ public static function get_networks(): array {
+ return [
+ 'icq' => get_string('icqnumber', 'profilefield_social'),
+ 'msn' => get_string('msnid', 'profilefield_social'),
+ 'aim' => get_string('aimid', 'profilefield_social'),
+ 'yahoo' => get_string('yahooid', 'profilefield_social'),
+ 'skype' => get_string('skypeid', 'profilefield_social'),
+ 'url' => get_string('webpage', 'profilefield_social'),
+ ];
+ }
+
+ /**
+ * Get the translated fieldname string for a network.
+ *
+ * @param string $fieldname Network short name.
+ * @return string network name.
+ */
+ public static function get_fieldname(string $fieldname): string {
+ $networks = self::get_networks();
+ return $networks[$fieldname];
+ }
+
+ /**
+ * Get the available network url formats.
+ *
+ * @return array list network url strings.
+ */
+ public static function get_network_urls(): array {
+ return [
+ 'skype' => '%%DATA%%',
+ 'icq' => '%%DATA%%',
+ 'url' => '%%DATA%%'
+ ];
+ }
+}
diff --git a/user/profile/field/social/classes/privacy/provider.php b/user/profile/field/social/classes/privacy/provider.php
new file mode 100644
index 00000000000..8c3c458c21a
--- /dev/null
+++ b/user/profile/field/social/classes/privacy/provider.php
@@ -0,0 +1,214 @@
+.
+
+/**
+ * Privacy class for requesting user data.
+ *
+ * @package profilefield_social
+ * @copyright 2020 Bas Brands
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace profilefield_social\privacy;
+
+defined('MOODLE_INTERNAL') || die();
+
+use \core_privacy\local\metadata\collection;
+use \core_privacy\local\request\contextlist;
+use \core_privacy\local\request\approved_contextlist;
+use core_privacy\local\request\userlist;
+use core_privacy\local\request\approved_userlist;
+
+/**
+ * Privacy class for requesting user data.
+ *
+ * @copyright 2018 Mihail Geshoski
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class provider implements
+ \core_privacy\local\metadata\provider,
+ \core_privacy\local\request\core_userlist_provider,
+ \core_privacy\local\request\plugin\provider {
+
+ /**
+ * Returns meta data about this system.
+ *
+ * @param collection $collection The initialised collection to add items to.
+ * @return collection A listing of user data stored through this system.
+ */
+ public static function get_metadata(collection $collection) : collection {
+ return $collection->add_database_table('user_info_data', [
+ 'userid' => 'privacy:metadata:profile_field_social:userid',
+ 'fieldid' => 'privacy:metadata:profile_field_social:fieldid',
+ 'data' => 'privacy:metadata:profile_field_social:data',
+ 'dataformat' => 'privacy:metadata:profile_field_social:dataformat'
+ ], 'privacy:metadata:profile_field_social:tableexplanation');
+ }
+
+ /**
+ * Get the list of contexts that contain user information for the specified user.
+ *
+ * @param int $userid The user to search.
+ * @return contextlist $contextlist The contextlist containing the list of contexts used in this plugin.
+ */
+ public static function get_contexts_for_userid(int $userid) : contextlist {
+ $sql = "SELECT ctx.id
+ FROM {user_info_data} uda
+ JOIN {user_info_field} uif ON uda.fieldid = uif.id
+ JOIN {context} ctx ON ctx.instanceid = uda.userid
+ AND ctx.contextlevel = :contextlevel
+ WHERE uda.userid = :userid
+ AND uif.datatype = :datatype";
+ $params = [
+ 'userid' => $userid,
+ 'contextlevel' => CONTEXT_USER,
+ 'datatype' => 'social'
+ ];
+ $contextlist = new contextlist();
+ $contextlist->add_from_sql($sql, $params);
+
+ return $contextlist;
+ }
+
+ /**
+ * Get the list of users within a specific context.
+ *
+ * @param userlist $userlist The userlist containing the list of users who have data in this context/plugin combination.
+ */
+ public static function get_users_in_context(userlist $userlist) {
+ $context = $userlist->get_context();
+
+ if (!$context instanceof \context_user) {
+ return;
+ }
+
+ $sql = "SELECT uda.userid
+ FROM {user_info_data} uda
+ JOIN {user_info_field} uif
+ ON uda.fieldid = uif.id
+ WHERE uda.userid = :userid
+ AND uif.datatype = :datatype";
+
+ $params = [
+ 'userid' => $context->instanceid,
+ 'datatype' => 'social'
+ ];
+
+ $userlist->add_from_sql('userid', $sql, $params);
+ }
+
+ /**
+ * Export all user data for the specified user, in the specified contexts.
+ *
+ * @param approved_contextlist $contextlist The approved contexts to export information for.
+ */
+ public static function export_user_data(approved_contextlist $contextlist) {
+ $user = $contextlist->get_user();
+ foreach ($contextlist->get_contexts() as $context) {
+ // Check if the context is a user context.
+ if ($context->contextlevel == CONTEXT_USER && $context->instanceid == $user->id) {
+ $results = static::get_records($user->id);
+ foreach ($results as $result) {
+ $data = (object) [
+ 'name' => $result->name,
+ 'description' => $result->description,
+ 'data' => $result->data
+ ];
+ \core_privacy\local\request\writer::with_context($context)->export_data([
+ get_string('pluginname', 'profilefield_social')], $data);
+ }
+ }
+ }
+ }
+
+ /**
+ * Delete all user data which matches the specified context.
+ *
+ * @param context $context A user context.
+ */
+ public static function delete_data_for_all_users_in_context(\context $context) {
+ // Delete data only for user context.
+ if ($context->contextlevel == CONTEXT_USER) {
+ static::delete_data($context->instanceid);
+ }
+ }
+
+ /**
+ * Delete multiple users within a single context.
+ *
+ * @param approved_userlist $userlist The approved context and user information to delete information for.
+ */
+ public static function delete_data_for_users(approved_userlist $userlist) {
+ $context = $userlist->get_context();
+
+ if ($context instanceof \context_user) {
+ static::delete_data($context->instanceid);
+ }
+ }
+
+ /**
+ * Delete all user data for the specified user, in the specified contexts.
+ *
+ * @param approved_contextlist $contextlist The approved contexts and user information to delete information for.
+ */
+ public static function delete_data_for_user(approved_contextlist $contextlist) {
+ $user = $contextlist->get_user();
+ foreach ($contextlist->get_contexts() as $context) {
+ // Check if the context is a user context.
+ if ($context->contextlevel == CONTEXT_USER && $context->instanceid == $user->id) {
+ static::delete_data($context->instanceid);
+ }
+ }
+ }
+
+ /**
+ * Delete data related to a userid.
+ *
+ * @param int $userid The user ID
+ */
+ protected static function delete_data($userid) {
+ global $DB;
+ $params = [
+ 'userid' => $userid,
+ 'datatype' => 'social'
+ ];
+
+ $DB->delete_records_select('user_info_data', "fieldid IN (
+ SELECT id FROM {user_info_field} WHERE datatype = :datatype)
+ AND userid = :userid", $params);
+ }
+
+ /**
+ * Get records related to this plugin and user.
+ *
+ * @param int $userid The user ID
+ * @return array An array of records.
+ */
+ protected static function get_records($userid) {
+ global $DB;
+ $sql = "SELECT *
+ FROM {user_info_data} uda
+ JOIN {user_info_field} uif ON uda.fieldid = uif.id
+ WHERE uda.userid = :userid
+ AND uif.datatype = :datatype";
+ $params = [
+ 'userid' => $userid,
+ 'datatype' => 'social'
+ ];
+
+ return $DB->get_records_sql($sql, $params);
+ }
+}
diff --git a/user/profile/field/social/define.class.php b/user/profile/field/social/define.class.php
new file mode 100644
index 00000000000..61a02fc4b8e
--- /dev/null
+++ b/user/profile/field/social/define.class.php
@@ -0,0 +1,95 @@
+.
+
+/**
+ * Textarea profile field define.
+ *
+ * @package profilefield_social
+ * @copyright 2020 Bas Brands
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+/**
+ * Class profile_define_social.
+ *
+ * @copyright 2020 Bas Brands
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class profile_define_social extends profile_define_base {
+
+ /**
+ * Prints out the form snippet for the part of creating or editing a profile field common to all data types.
+ *
+ * @param moodleform $form instance of the moodleform class
+ */
+ public function define_form_common(&$form) {
+ $availablenetworks = profilefield_social\helper::get_networks();
+ $networks = array_merge(['0' => get_string('select')], $availablenetworks);
+
+ $form->addElement('hidden', 'defaultdata', '');
+ $form->setType('defaultdata', PARAM_TEXT);
+
+ $form->addElement('select', 'param1', get_string('networktype', 'profilefield_social'), $networks);
+ $form->addRule('param1', get_string('required'), 'required', null, 'client');
+ $form->setType('param1', PARAM_TEXT);
+
+ parent::define_form_common($form);
+ $form->removeElement('name');
+ }
+
+ /**
+ * Alter form based on submitted or existing data.
+ *
+ * @param moodleform $form
+ */
+ public function define_after_data(&$form) {
+ if (isset($form->_defaultValues['name'])) {
+ $form->setDefault('param1', $form->_defaultValues['name']);
+ }
+ }
+
+ /**
+ * Validate the data from the add/edit profile field form that is common to all data types.
+ *
+ * Generally this method should not be overwritten by child classes.
+ *
+ * @param stdClass|array $data from the add/edit profile field form
+ * @param array $files
+ * @return array associative array of error messages
+ */
+ public function define_validate_common($data, $files) {
+ $err = parent::define_validate_common($data, $files);
+
+ $networks = profilefield_social\helper::get_networks();
+ if (empty($data->param1) || !array_key_exists($data->param1, $networks)) {
+ $err['param1'] = get_string('invalidnetwork', 'profilefield_social');
+ }
+ return $err;
+ }
+
+ /**
+ * Preprocess data from the add/edit profile field form before it is saved.
+ *
+ * This method is a hook for the child classes to overwrite.
+ *
+ * @param array|stdClass $data from the add/edit profile field form
+ * @return array|stdClass processed data object
+ */
+ public function define_save_preprocess($data) {
+ $data->name = $data->param1;
+ return $data;
+ }
+}
diff --git a/user/profile/field/social/field.class.php b/user/profile/field/social/field.class.php
new file mode 100644
index 00000000000..ad44f233e8d
--- /dev/null
+++ b/user/profile/field/social/field.class.php
@@ -0,0 +1,84 @@
+.
+
+/**
+ * Social profile field define.
+ *
+ * @package profilefield_social
+ * @copyright 2020 Bas Brands
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+/**
+ * Class profile_field_social.
+ *
+ * @copyright 2020 Bas Brands
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class profile_field_social extends profile_field_base {
+
+ /**
+ * Adds elements for this field type to the edit form.
+ * @param moodleform $mform
+ */
+ public function edit_field_add($mform) {
+ $mform->addElement('text', $this->inputname, $this->field->name, null, null);
+ if ($this->field->param1 === 'url') {
+ $mform->setType($this->inputname, PARAM_URL);
+ } else {
+ $mform->setType($this->inputname, PARAM_NOTAGS);
+ }
+ }
+
+ /**
+ * alter the fieldname to be fetched from the language file.
+ *
+ * @param stdClass $field
+ */
+ public function set_field($field) {
+ $networks = profilefield_social\helper::get_networks();
+ $field->name = $networks[$field->name];
+ parent::set_field($field);
+ }
+
+ /**
+ * Display the data for this field
+ * @return string
+ */
+ public function display_data() {
+ $network = $this->field->param1;
+ $networkurls = profilefield_social\helper::get_network_urls();
+
+ if (array_key_exists($network, $networkurls)) {
+ return str_replace('%%DATA%%', $this->data, $networkurls[$network]);
+ }
+
+ return $this->data;
+ }
+
+ /**
+ * Return the field type and null properties.
+ * This will be used for validating the data submitted by a user.
+ *
+ * @return array the param type and null property
+ * @since Moodle 3.2
+ */
+ public function get_field_properties() {
+ return array(PARAM_TEXT, NULL_NOT_ALLOWED);
+ }
+}
+
+
diff --git a/user/profile/field/social/lang/en/profilefield_social.php b/user/profile/field/social/lang/en/profilefield_social.php
new file mode 100644
index 00000000000..8c90e6f5c86
--- /dev/null
+++ b/user/profile/field/social/lang/en/profilefield_social.php
@@ -0,0 +1,39 @@
+.
+
+/**
+ * Strings for component 'profilefield_social'
+ *
+ * @package profilefield_social
+ * @copyright 2020 Bas Brands
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+$string['invalidnetwork'] = 'Invalid social network';
+$string['networkinuse'] = 'Social network has already been added';
+$string['pluginname'] = 'Social';
+$string['networktype'] = 'Networktype';
+$string['privacy:metadata:profile_field_social:data'] = 'Text area user profile field user data';
+$string['privacy:metadata:profile_field_social:dataformat'] = 'The format of Text area user profile field user data';
+$string['privacy:metadata:profile_field_social:fieldid'] = 'The ID of the profile field';
+$string['privacy:metadata:profile_field_social:tableexplanation'] = 'Additional profile data';
+$string['privacy:metadata:profile_field_social:userid'] = 'The ID of the user whose data is stored by the social user profile field';
+$string['aimid'] = 'AIM ID';
+$string['yahooid'] = 'Yahoo ID';
+$string['skypeid'] = 'Skype ID';
+$string['icqnumber'] = 'ICQ number';
+$string['msnid'] = 'MSN ID';
+$string['webpage'] = 'Web page';
diff --git a/user/profile/field/social/tests/privacy_test.php b/user/profile/field/social/tests/privacy_test.php
new file mode 100644
index 00000000000..4c336f04b32
--- /dev/null
+++ b/user/profile/field/social/tests/privacy_test.php
@@ -0,0 +1,312 @@
+.
+
+/**
+ * Base class for unit tests for profilefield_social.
+ *
+ * @package profilefield_social
+ * @copyright 2020 Bas Brands
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+use \core_privacy\tests\provider_testcase;
+use profilefield_social\privacy\provider;
+use core_privacy\local\request\approved_userlist;
+
+/**
+ * Unit tests for user\profile\field\social\classes\privacy\provider.php
+ *
+ * @copyright 2020 Bas Brands
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class profilefield_social_testcase extends provider_testcase {
+
+ /**
+ * Basic setup for these tests.
+ */
+ public function setUp(): void {
+ $this->resetAfterTest(true);
+ }
+
+ /**
+ * Test getting the context for the user ID related to this plugin.
+ */
+ public function test_get_contexts_for_userid() {
+ global $DB;
+ // Create profile category.
+ $categoryid = $this->add_profile_category();
+ // Create profile field.
+ $profilefieldid = $this->add_profile_field($categoryid, 'social');
+ // Create a user.
+ $user = $this->getDataGenerator()->create_user();
+ $this->add_user_info_data($user->id, $profilefieldid, 'test data');
+ // Get the field that was created.
+ $userfielddata = $DB->get_records('user_info_data', array('userid' => $user->id));
+ // Confirm we got the right number of user field data.
+ $this->assertCount(1, $userfielddata);
+ $context = context_user::instance($user->id);
+ $contextlist = provider::get_contexts_for_userid($user->id);
+ $this->assertEquals($context, $contextlist->current());
+ }
+
+ /**
+ * Test that data is exported correctly for this plugin.
+ */
+ public function test_export_user_data() {
+ // Create profile category.
+ $categoryid = $this->add_profile_category();
+ // Create social profile field.
+ $socialprofilefieldid = $this->add_profile_field($categoryid, 'social');
+ // Create checkbox profile field.
+ $checkboxprofilefieldid = $this->add_profile_field($categoryid, 'checkbox');
+ // Create a user.
+ $user = $this->getDataGenerator()->create_user();
+ $context = context_user::instance($user->id);
+ // Add social user info data.
+ $this->add_user_info_data($user->id, $socialprofilefieldid, '#icq-1294923');
+ // Add checkbox user info data.
+ $this->add_user_info_data($user->id, $checkboxprofilefieldid, 'test data');
+ $writer = \core_privacy\local\request\writer::with_context($context);
+ $this->assertFalse($writer->has_any_data());
+ $this->export_context_data_for_user($user->id, $context, 'profilefield_social');
+ $data = $writer->get_data([get_string('pluginname', 'profilefield_social')]);
+ $this->assertCount(3, (array) $data);
+ $this->assertEquals('icq', $data->name);
+ $this->assertEquals('', $data->description);
+ $this->assertEquals('#icq-1294923', $data->data);
+ }
+
+ /**
+ * Test that user data is deleted using the context.
+ */
+ public function test_delete_data_for_all_users_in_context() {
+ global $DB;
+ // Create profile category.
+ $categoryid = $this->add_profile_category();
+ // Create social profile field.
+ $socialprofilefieldid = $this->add_profile_field($categoryid, 'social');
+ // Create checkbox profile field.
+ $checkboxprofilefieldid = $this->add_profile_field($categoryid, 'checkbox');
+ // Create a user.
+ $user = $this->getDataGenerator()->create_user();
+ $context = context_user::instance($user->id);
+ // Add social user info data.
+ $this->add_user_info_data($user->id, $socialprofilefieldid, '#icq-1294923');
+ // Add checkbox user info data.
+ $this->add_user_info_data($user->id, $checkboxprofilefieldid, 'test data');
+ // Check that we have two entries.
+ $userinfodata = $DB->get_records('user_info_data', ['userid' => $user->id]);
+ $this->assertCount(2, $userinfodata);
+ provider::delete_data_for_all_users_in_context($context);
+ // Check that the correct profile field has been deleted.
+ $userinfodata = $DB->get_records('user_info_data', ['userid' => $user->id]);
+ $this->assertCount(1, $userinfodata);
+ $this->assertNotEquals('#icq-1294923', reset($userinfodata)->data);
+ }
+
+ /**
+ * Test that user data is deleted for this user.
+ */
+ public function test_delete_data_for_user() {
+ global $DB;
+ // Create profile category.
+ $categoryid = $this->add_profile_category();
+ // Create social profile field.
+ $socialprofilefieldid = $this->add_profile_field($categoryid, 'social');
+ // Create checkbox profile field.
+ $checkboxprofilefieldid = $this->add_profile_field($categoryid, 'checkbox');
+ // Create a user.
+ $user = $this->getDataGenerator()->create_user();
+ $context = context_user::instance($user->id);
+ // Add social user info data.
+ $this->add_user_info_data($user->id, $socialprofilefieldid, '#icq-1294923');
+ // Add checkbox user info data.
+ $this->add_user_info_data($user->id, $checkboxprofilefieldid, 'test data');
+ // Check that we have two entries.
+ $userinfodata = $DB->get_records('user_info_data', ['userid' => $user->id]);
+ $this->assertCount(2, $userinfodata);
+ $approvedlist = new \core_privacy\local\request\approved_contextlist($user, 'profilefield_social',
+ [$context->id]);
+ provider::delete_data_for_user($approvedlist);
+ // Check that the correct profile field has been deleted.
+ $userinfodata = $DB->get_records('user_info_data', ['userid' => $user->id]);
+ $this->assertCount(1, $userinfodata);
+ $this->assertNotEquals('#icq-1294923', reset($userinfodata)->data);
+ }
+
+ /**
+ * Test that only users with a user context are fetched.
+ */
+ public function test_get_users_in_context() {
+ $this->resetAfterTest();
+
+ $component = 'profilefield_social';
+ // Create profile category.
+ $categoryid = $this->add_profile_category();
+ // Create profile field.
+ $profilefieldid = $this->add_profile_field($categoryid, 'social');
+
+ // Create a user.
+ $user = $this->getDataGenerator()->create_user();
+ $usercontext = context_user::instance($user->id);
+ // The list of users should not return anything yet (related data still haven't been created).
+ $userlist = new \core_privacy\local\request\userlist($usercontext, $component);
+ provider::get_users_in_context($userlist);
+ $this->assertCount(0, $userlist);
+
+ $this->add_user_info_data($user->id, $profilefieldid, 'test data');
+
+ // The list of users for user context should return the user.
+ provider::get_users_in_context($userlist);
+ $this->assertCount(1, $userlist);
+ $expected = [$user->id];
+ $actual = $userlist->get_userids();
+ $this->assertEquals($expected, $actual);
+
+ // The list of users for system context should not return any users.
+ $systemcontext = context_system::instance();
+ $userlist = new \core_privacy\local\request\userlist($systemcontext, $component);
+ provider::get_users_in_context($userlist);
+ $this->assertCount(0, $userlist);
+ }
+
+ /**
+ * Test that data for users in approved userlist is deleted.
+ */
+ public function test_delete_data_for_users() {
+ $this->resetAfterTest();
+
+ $component = 'profilefield_social';
+ // Create profile category.
+ $categoryid = $this->add_profile_category();
+ // Create profile field.
+ $profilefieldid = $this->add_profile_field($categoryid, 'social');
+
+ // Create user1.
+ $user1 = $this->getDataGenerator()->create_user();
+ $usercontext1 = context_user::instance($user1->id);
+ // Create user2.
+ $user2 = $this->getDataGenerator()->create_user();
+ $usercontext2 = context_user::instance($user2->id);
+
+ $this->add_user_info_data($user1->id, $profilefieldid, 'test data');
+ $this->add_user_info_data($user2->id, $profilefieldid, 'test data');
+
+ // The list of users for usercontext1 should return user1.
+ $userlist1 = new \core_privacy\local\request\userlist($usercontext1, $component);
+ provider::get_users_in_context($userlist1);
+ $this->assertCount(1, $userlist1);
+ $expected = [$user1->id];
+ $actual = $userlist1->get_userids();
+ $this->assertEquals($expected, $actual);
+
+ // The list of users for usercontext2 should return user2.
+ $userlist2 = new \core_privacy\local\request\userlist($usercontext2, $component);
+ provider::get_users_in_context($userlist2);
+ $this->assertCount(1, $userlist2);
+ $expected = [$user2->id];
+ $actual = $userlist2->get_userids();
+ $this->assertEquals($expected, $actual);
+
+ // Add userlist1 to the approved user list.
+ $approvedlist = new approved_userlist($usercontext1, $component, $userlist1->get_userids());
+
+ // Delete user data using delete_data_for_user for usercontext1.
+ provider::delete_data_for_users($approvedlist);
+
+ // Re-fetch users in usercontext1 - The user list should now be empty.
+ $userlist1 = new \core_privacy\local\request\userlist($usercontext1, $component);
+ provider::get_users_in_context($userlist1);
+ $this->assertCount(0, $userlist1);
+
+ // Re-fetch users in usercontext2 - The user list should not be empty (user2).
+ $userlist2 = new \core_privacy\local\request\userlist($usercontext2, $component);
+ provider::get_users_in_context($userlist2);
+ $this->assertCount(1, $userlist2);
+
+ // User data should be only removed in the user context.
+ $systemcontext = context_system::instance();
+ // Add userlist2 to the approved user list in the system context.
+ $approvedlist = new approved_userlist($systemcontext, $component, $userlist2->get_userids());
+ // Delete user1 data using delete_data_for_user.
+ provider::delete_data_for_users($approvedlist);
+ // Re-fetch users in usercontext2 - The user list should not be empty (user2).
+ $userlist1 = new \core_privacy\local\request\userlist($usercontext2, $component);
+ provider::get_users_in_context($userlist1);
+ $this->assertCount(1, $userlist1);
+ }
+
+ /**
+ * Add dummy user info data.
+ *
+ * @param int $userid The ID of the user
+ * @param int $fieldid The ID of the field
+ * @param string $data The data
+ */
+ private function add_user_info_data($userid, $fieldid, $data) {
+ global $DB;
+ $userinfodata = array(
+ 'userid' => $userid,
+ 'fieldid' => $fieldid,
+ 'data' => $data,
+ 'dataformat' => 0
+ );
+
+ $DB->insert_record('user_info_data', $userinfodata);
+ }
+
+ /**
+ * Add dummy profile category.
+ *
+ * @return int The ID of the profile category
+ */
+ private function add_profile_category() {
+ global $DB;
+ // Create a new profile category.
+ $cat = new stdClass();
+ $cat->name = 'Test category';
+ $cat->sortorder = 1;
+
+ return $DB->insert_record('user_info_category', $cat);
+ }
+
+ /**
+ * Add dummy profile field.
+ *
+ * @param int $categoryid The ID of the profile category
+ * @param string $datatype The datatype of the profile field
+ * @return int The ID of the profile field
+ */
+ private function add_profile_field($categoryid, $datatype) {
+ global $DB;
+ // Create a new profile field.
+ $data = new stdClass();
+ $data->datatype = $datatype;
+ $data->shortname = 'icq';
+ $data->name = 'icq';
+ $data->description = '';
+ $data->required = false;
+ $data->locked = false;
+ $data->forceunique = false;
+ $data->signup = false;
+ $data->visible = '0';
+ $data->categoryid = $categoryid;
+
+ return $DB->insert_record('user_info_field', $data);
+ }
+}
diff --git a/user/profile/field/social/upgradelib.php b/user/profile/field/social/upgradelib.php
new file mode 100644
index 00000000000..23387180ef8
--- /dev/null
+++ b/user/profile/field/social/upgradelib.php
@@ -0,0 +1,187 @@
+.
+
+/**
+ * Contains upgrade and install functions for the social profile fields.
+ *
+ * @package profilefield_social
+ * @copyright 2020 Bas Brands
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+require_once("$CFG->dirroot/user/profile/definelib.php");
+
+/**
+ * Create the default category for custom profile fields if it does not exist yet.
+ */
+function user_profile_social_create_info_category() {
+ global $DB;
+
+ $categories = $DB->get_records('user_info_category', null, 'sortorder ASC');
+ // Check that we have at least one category defined.
+ if (empty($categories)) {
+ $defaultcategory = (object) [
+ 'name' => get_string('profiledefaultcategory', 'admin'),
+ 'sortorder' => 1
+ ];
+ $DB->insert_record('user_info_category', $defaultcategory);
+ }
+}
+
+/**
+ * Called on upgrade to create new profile fields based on the old user table columns
+ * for icq, msn, aim, skype and url.
+ *
+ * @param string $social Social profile field.
+ */
+function user_profile_social_moveto_profilefield($social) {
+ global $DB;
+
+ $users = $DB->get_records_select('user', "$social IS NOT NULL AND $social != ''");
+ if (count($users)) {
+ $profilefield = user_profile_social_create_profilefield($social);
+ foreach ($users as $user) {
+ $userinfodata = [
+ 'userid' => $user->id,
+ 'fieldid' => $profilefield->id,
+ 'data' => $user->$social,
+ 'dataformat' => 0
+ ];
+ $user->$social = '';
+ $DB->update_record('user', $user);
+ $DB->insert_record('user_info_data', $userinfodata);
+ }
+ }
+}
+
+/**
+ * Create an new custom social profile field if it does not exist
+ *
+ * @param string $social Social profile field.
+ * @return object DB record or social profield field.
+ */
+function user_profile_social_create_profilefield($social) {
+ global $DB, $CFG;
+
+ $hiddenfields = explode(',', $CFG->hiddenuserfields);
+ $confignames = [
+ 'url' => 'webpage',
+ 'icq' => 'icqnumber',
+ 'skype' => 'skypeid',
+ 'yahoo' => 'yahooid',
+ 'aim' => 'aimid',
+ 'msn' => 'msnid',
+ ];
+ $visible = (in_array($confignames[$social], $hiddenfields)) ? 3 : 2;
+
+ $newfield = (object)[
+ 'shortname' => $social,
+ 'name' => $social,
+ 'datatype' => 'social',
+ 'description' => '',
+ 'descriptionformat' => 1,
+ 'categoryid' => 1,
+ 'required' => 0,
+ 'locked' => 0,
+ 'visible' => $visible,
+ 'forceunique' => 0,
+ 'signup' => 0,
+ 'defaultdata' => '',
+ 'defaultdataformat' => 0,
+ 'param1' => $social
+ ];
+
+ user_profile_social_create_info_category();
+
+ $profilefield = $DB->get_record_sql(
+ 'SELECT * FROM {user_info_field} WHERE datatype = :datatype AND ' .
+ $DB->sql_compare_text('param1') . ' = ' . $DB->sql_compare_text(':social', 40),
+ ['datatype' => 'social', 'social' => $social]);
+
+ if (!$profilefield) {
+
+ // Find a new unique shortname.
+ $count = 0;
+ $shortname = $newfield->shortname;
+ while ($field = $DB->get_record('user_info_field', array('shortname' => $shortname))) {
+ $count++;
+ $shortname = $newfield->shortname . '_' . $count;
+ }
+ $newfield->shortname = $shortname;
+
+ $profileclass = new profile_define_base();
+ $profileclass->define_save($newfield);
+ profile_reorder_fields();
+
+ $profilefield = $DB->get_record_sql(
+ 'SELECT * FROM {user_info_field} WHERE datatype = :datatype AND ' .
+ $DB->sql_compare_text('param1') . ' = ' . $DB->sql_compare_text(':social', 40),
+ ['datatype' => 'social', 'social' => $social]);
+ }
+ if (!$profilefield) {
+ throw new moodle_exception('upgradeerror', 'admin', 'could not create new social profile field');
+ }
+ return $profilefield;
+}
+
+/**
+ * Update the module availability configuration for all course modules
+ *
+ */
+function user_profile_social_update_module_availability() {
+ global $DB;
+ $modules = $DB->get_records('course_modules');
+ foreach ($modules as $mod) {
+ if (isset($mod->availability)) {
+ $availability = json_decode($mod->availability);
+ if (!is_null($availability)) {
+ user_profile_social_update_availability_structure($availability);
+ $newavailability = json_encode($availability);
+ if ($newavailability !== $mod->availability) {
+ $mod->availability = json_encode($availability);
+ $DB->update_record('course_modules', $mod);
+ }
+ }
+ }
+ }
+}
+
+/**
+ * Loop through the availability info and change all move standard profile
+ * fields for icq, skype, aim, yahoo, msn and url to be custom profile fields.
+ * @param mixed $structure The availability object.
+ */
+function user_profile_social_update_availability_structure(&$structure) {
+ if (is_array($structure)) {
+ foreach ($structure as $st) {
+ user_profile_social_update_availability_structure($st);
+ }
+ }
+ foreach ($structure as $key => $value) {
+ if ($key === 'c' && is_array($value)) {
+ user_profile_social_update_availability_structure($value);
+ }
+ if ($key === 'type' && $value === 'profile') {
+ if (isset($structure->sf) && in_array($structure->sf,
+ ['icq', 'skype', 'aim', 'yahoo', 'msn', 'url'])) {
+ $structure->cf = $structure->sf;
+ unset($structure->sf);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/user/profile/field/social/version.php b/user/profile/field/social/version.php
new file mode 100644
index 00000000000..1587c1388ff
--- /dev/null
+++ b/user/profile/field/social/version.php
@@ -0,0 +1,29 @@
+.
+
+/**
+ * Version information for the social profile field.
+ *
+ * @package profilefield_social
+ * @copyright 2020 Bas Brands
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+$plugin->version = 2021052500;
+$plugin->requires = 2021020400;
+$plugin->component = 'profilefield_social';
diff --git a/user/profile/index.php b/user/profile/index.php
index 799980c875f..ae55294ed12 100644
--- a/user/profile/index.php
+++ b/user/profile/index.php
@@ -134,7 +134,13 @@ foreach ($categories as $category) {
if ($fields = $DB->get_records('user_info_field', array('categoryid' => $category->id), 'sortorder ASC')) {
foreach ($fields as $field) {
- $table->data[] = array(format_string($field->name), profile_field_icons($field));
+ $fieldname = format_string($field->name);
+ $component = 'profilefield_' . $field->datatype;
+ $classname = "\\$component\\helper";
+ if (class_exists($classname) && method_exists($classname, 'get_fieldname')) {
+ $fieldname = $classname::get_fieldname($field->name);
+ }
+ $table->data[] = array($fieldname, profile_field_icons($field));
}
}
diff --git a/user/profile/lib.php b/user/profile/lib.php
index 33dc3c85b8b..6d9c1de6e0d 100644
--- a/user/profile/lib.php
+++ b/user/profile/lib.php
@@ -810,6 +810,14 @@ function profile_get_custom_fields($onlyinuserobject = false) {
}
}
+ foreach ($fields as $index => $field) {
+ $component = 'profilefield_' . $field->datatype;
+ $classname = "\\$component\\helper";
+ if (class_exists($classname) && method_exists($classname, 'get_fieldname')) {
+ $fields[$index]->name = $classname::get_fieldname($field->name);
+ }
+ }
+
return $fields;
}
diff --git a/user/tests/externallib_test.php b/user/tests/externallib_test.php
index 3c6b4de806d..f2a6176745c 100644
--- a/user/tests/externallib_test.php
+++ b/user/tests/externallib_test.php
@@ -53,17 +53,11 @@ class core_user_externallib_testcase extends externallib_advanced_testcase {
'address' => '2 Test Street Perth 6000 WA',
'phone1' => '01010101010',
'phone2' => '02020203',
- 'icq' => 'testuser1',
- 'skype' => 'testuser1',
- 'yahoo' => 'testuser1',
- 'aim' => 'testuser1',
- 'msn' => 'testuser1',
'department' => 'Department of user 1',
'institution' => 'Institution of user 1',
'description' => 'This is a description for user 1',
'descriptionformat' => FORMAT_MOODLE,
'city' => 'Perth',
- 'url' => 'http://moodle.org',
'country' => 'AU'
);
@@ -128,21 +122,6 @@ class core_user_externallib_testcase extends externallib_advanced_testcase {
if (!empty($generateduser->phone2)) {
$this->assertEquals($generateduser->phone2, $returneduser['phone2']);
}
- if (!empty($generateduser->icq)) {
- $this->assertEquals($generateduser->icq, $returneduser['icq']);
- }
- if (!empty($generateduser->skype)) {
- $this->assertEquals($generateduser->skype, $returneduser['skype']);
- }
- if (!empty($generateduser->yahoo)) {
- $this->assertEquals($generateduser->yahoo, $returneduser['yahoo']);
- }
- if (!empty($generateduser->aim)) {
- $this->assertEquals($generateduser->aim, $returneduser['aim']);
- }
- if (!empty($generateduser->msn)) {
- $this->assertEquals($generateduser->msn, $returneduser['msn']);
- }
if (!empty($generateduser->department)) {
$this->assertEquals($generateduser->department, $returneduser['department']);
}
@@ -161,9 +140,6 @@ class core_user_externallib_testcase extends externallib_advanced_testcase {
if (!empty($generateduser->country)) {
$this->assertEquals($generateduser->country, $returneduser['country']);
}
- if (!empty($generateduser->url)) {
- $this->assertEquals($generateduser->url, $returneduser['url']);
- }
if (!empty($CFG->usetags) and !empty($generateduser->interests)) {
$this->assertEquals(implode(', ', $generateduser->interests), $returneduser['interests']);
}
@@ -211,17 +187,11 @@ class core_user_externallib_testcase extends externallib_advanced_testcase {
'address' => '2 Test Street Perth 6000 WA',
'phone1' => '01010101010',
'phone2' => '02020203',
- 'icq' => 'testuser1',
- 'skype' => 'testuser1',
- 'yahoo' => 'testuser1',
- 'aim' => 'testuser1',
- 'msn' => 'testuser1',
'department' => 'Department of user 1',
'institution' => 'Institution of user 1',
'description' => 'This is a description for user 1',
'descriptionformat' => FORMAT_MOODLE,
'city' => 'Perth',
- 'url' => 'http://moodle.org',
'country' => 'AU',
);
$user1 = self::getDataGenerator()->create_user($user1);
@@ -289,21 +259,6 @@ class core_user_externallib_testcase extends externallib_advanced_testcase {
if (!empty($generateduser->phone2)) {
$this->assertEquals($generateduser->phone2, $returneduser['phone2']);
}
- if (!empty($generateduser->icq)) {
- $this->assertEquals($generateduser->icq, $returneduser['icq']);
- }
- if (!empty($generateduser->skype)) {
- $this->assertEquals($generateduser->skype, $returneduser['skype']);
- }
- if (!empty($generateduser->yahoo)) {
- $this->assertEquals($generateduser->yahoo, $returneduser['yahoo']);
- }
- if (!empty($generateduser->aim)) {
- $this->assertEquals($generateduser->aim, $returneduser['aim']);
- }
- if (!empty($generateduser->msn)) {
- $this->assertEquals($generateduser->msn, $returneduser['msn']);
- }
if (!empty($generateduser->department)) {
$this->assertEquals($generateduser->department, $returneduser['department']);
}
@@ -322,9 +277,6 @@ class core_user_externallib_testcase extends externallib_advanced_testcase {
if (!empty($generateduser->country)) {
$this->assertEquals($generateduser->country, $returneduser['country']);
}
- if (!empty($generateduser->url)) {
- $this->assertEquals($generateduser->url, $returneduser['url']);
- }
if (!empty($CFG->usetags) and !empty($generateduser->interests)) {
$this->assertEquals(implode(', ', $generateduser->interests), $returneduser['interests']);
}
@@ -375,17 +327,11 @@ class core_user_externallib_testcase extends externallib_advanced_testcase {
'address' => '2 Test Street Perth 6000 WA',
'phone1' => '01010101010',
'phone2' => '02020203',
- 'icq' => 'testuser1',
- 'skype' => 'testuser1',
- 'yahoo' => 'testuser1',
- 'aim' => 'testuser1',
- 'msn' => 'testuser1',
'department' => 'Department of user 1',
'institution' => 'Institution of user 1',
'description' => 'This is a description for user 1',
'descriptionformat' => FORMAT_MOODLE,
'city' => 'Perth',
- 'url' => 'http://moodle.org',
'country' => 'AU'
);
$return->user1 = self::getDataGenerator()->create_user($return->user1);
@@ -457,18 +403,12 @@ class core_user_externallib_testcase extends externallib_advanced_testcase {
$this->assertEquals($data->user1->address, $enrolleduser['address']);
$this->assertEquals($data->user1->phone1, $enrolleduser['phone1']);
$this->assertEquals($data->user1->phone2, $enrolleduser['phone2']);
- $this->assertEquals($data->user1->icq, $enrolleduser['icq']);
- $this->assertEquals($data->user1->skype, $enrolleduser['skype']);
- $this->assertEquals($data->user1->yahoo, $enrolleduser['yahoo']);
- $this->assertEquals($data->user1->aim, $enrolleduser['aim']);
- $this->assertEquals($data->user1->msn, $enrolleduser['msn']);
$this->assertEquals($data->user1->department, $enrolleduser['department']);
$this->assertEquals($data->user1->institution, $enrolleduser['institution']);
$this->assertEquals($data->user1->description, $enrolleduser['description']);
$this->assertEquals(FORMAT_HTML, $enrolleduser['descriptionformat']);
$this->assertEquals($data->user1->city, $enrolleduser['city']);
$this->assertEquals($data->user1->country, $enrolleduser['country']);
- $this->assertEquals($data->user1->url, $enrolleduser['url']);
if (!empty($CFG->usetags)) {
$this->assertEquals(implode(', ', $data->user1->interests), $enrolleduser['interests']);
}
diff --git a/user/tests/privacy_test.php b/user/tests/privacy_test.php
index cedc5658bd3..6e6e0bfed7a 100644
--- a/user/tests/privacy_test.php
+++ b/user/tests/privacy_test.php
@@ -146,7 +146,6 @@ class core_user_privacy_testcase extends provider_testcase {
$user = $this->getDataGenerator()->create_user([
'idnumber' => 'A0023',
'emailstop' => 1,
- 'icq' => 'aksdjf98',
'phone1' => '555 3257',
'institution' => 'test',
'department' => 'Science',
@@ -187,7 +186,6 @@ class core_user_privacy_testcase extends provider_testcase {
$record = $DB->get_record('user', ['id' => $user->id]);
$this->assertEmpty($record->idnumber);
$this->assertEmpty($record->emailstop);
- $this->assertEmpty($record->icq);
$this->assertEmpty($record->phone1);
$this->assertEmpty($record->institution);
$this->assertEmpty($record->department);
@@ -217,7 +215,6 @@ class core_user_privacy_testcase extends provider_testcase {
$user = $this->getDataGenerator()->create_user([
'idnumber' => 'A0023',
'emailstop' => 1,
- 'icq' => 'aksdjf98',
'phone1' => '555 3257',
'institution' => 'test',
'department' => 'Science',
@@ -262,7 +259,6 @@ class core_user_privacy_testcase extends provider_testcase {
$record = $DB->get_record('user', ['id' => $user->id]);
$this->assertEmpty($record->idnumber);
$this->assertEmpty($record->emailstop);
- $this->assertEmpty($record->icq);
$this->assertEmpty($record->phone1);
$this->assertEmpty($record->institution);
$this->assertEmpty($record->department);
@@ -323,7 +319,6 @@ class core_user_privacy_testcase extends provider_testcase {
$user1 = $this->getDataGenerator()->create_user([
'idnumber' => 'A0023',
'emailstop' => 1,
- 'icq' => 'aksdjf98',
'phone1' => '555 3257',
'institution' => 'test',
'department' => 'Science',
@@ -337,7 +332,6 @@ class core_user_privacy_testcase extends provider_testcase {
$user2 = $this->getDataGenerator()->create_user([
'idnumber' => 'A0024',
'emailstop' => 1,
- 'icq' => 'aksdjf981',
'phone1' => '555 3258',
'institution' => 'test',
'department' => 'Science',
@@ -363,7 +357,6 @@ class core_user_privacy_testcase extends provider_testcase {
$record = $DB->get_record('user', ['id' => $user1->id]);
$this->assertEmpty($record->idnumber);
$this->assertEmpty($record->emailstop);
- $this->assertEmpty($record->icq);
$this->assertEmpty($record->phone1);
$this->assertEmpty($record->institution);
$this->assertEmpty($record->department);
@@ -387,7 +380,6 @@ class core_user_privacy_testcase extends provider_testcase {
$record = $DB->get_record('user', ['id' => $user2->id]);
$this->assertNotEmpty($record->idnumber);
$this->assertNotEmpty($record->emailstop);
- $this->assertNotEmpty($record->icq);
$this->assertNotEmpty($record->phone1);
$this->assertNotEmpty($record->institution);
$this->assertNotEmpty($record->department);
diff --git a/user/tests/userlib_test.php b/user/tests/userlib_test.php
index 51de4a67464..aaca2547d21 100644
--- a/user/tests/userlib_test.php
+++ b/user/tests/userlib_test.php
@@ -200,10 +200,9 @@ class core_userliblib_testcase extends advanced_testcase {
$user->lang = 'xy';
$user->theme = 'somewrongthemename';
$user->timezone = '30.5';
- $user->url = 'wwww.somewrong@#$url.com.aus';
$debugmessages = $this->getDebuggingMessages();
user_update_user($user, true, false);
- $this->assertDebuggingCalledCount(6, $debugmessages);
+ $this->assertDebuggingCalledCount(5, $debugmessages);
// Now, with valid user data.
$user->username = 'johndoe321';
@@ -212,7 +211,6 @@ class core_userliblib_testcase extends advanced_testcase {
$user->lang = 'en';
$user->theme = 'classic';
$user->timezone = 'Australia/Perth';
- $user->url = 'www.moodle.org';
user_update_user($user, true, false);
$this->assertDebuggingNotCalled();
}
@@ -283,10 +281,9 @@ class core_userliblib_testcase extends advanced_testcase {
$user['lang'] = 'xy';
$user['theme'] = 'somewrongthemename';
$user['timezone'] = '-30.5';
- $user['url'] = 'wwww.somewrong@#$url.com.aus';
$debugmessages = $this->getDebuggingMessages();
$user['id'] = user_create_user($user, true, false);
- $this->assertDebuggingCalledCount(6, $debugmessages);
+ $this->assertDebuggingCalledCount(5, $debugmessages);
$dbuser = $DB->get_record('user', array('id' => $user['id']));
$this->assertEquals($dbuser->country, 0);
$this->assertEquals($dbuser->lang, 'en');
@@ -299,7 +296,6 @@ class core_userliblib_testcase extends advanced_testcase {
$user['lang'] = 'en';
$user['theme'] = 'classic';
$user['timezone'] = 'Australia/Perth';
- $user['url'] = 'www.moodle.org';
user_create_user($user, true, false);
$this->assertDebuggingNotCalled();
}
diff --git a/version.php b/version.php
index d14d637af70..8cdb4438328 100644
--- a/version.php
+++ b/version.php
@@ -29,7 +29,7 @@
defined('MOODLE_INTERNAL') || die();
-$version = 2021052500.79; // YYYYMMDD = weekly release date of this DEV branch.
+$version = 2021052500.80; // YYYYMMDD = weekly release date of this DEV branch.
// RR = release increments - 00 in DEV branches.
// .XX = incremental changes.
$release = '4.0dev (Build: 20210416)'; // Human-friendly version name