Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.
   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  /**
  18   * Contains upgrade and install functions for the social profile fields.
  19   *
  20   * @package    profilefield_social
  21   * @copyright  2020 Bas Brands <bas@moodle.com>
  22   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  defined('MOODLE_INTERNAL') || die();
  26  
  27  require_once("$CFG->dirroot/user/profile/definelib.php");
  28  
  29  /**
  30   * Create the default category for custom profile fields if it does not exist yet.
  31   *
  32   * @return int Category ID for social user profile category.
  33   */
  34  function user_profile_social_create_info_category(): int {
  35      global $DB;
  36  
  37      $categories = $DB->get_records('user_info_category', null, 'sortorder ASC');
  38      // Check that we have at least one category defined.
  39      if (empty($categories)) {
  40          $defaultcategory = (object) [
  41              'name' => get_string('profiledefaultcategory', 'admin'),
  42              'sortorder' => 1
  43          ];
  44          return $DB->insert_record('user_info_category', $defaultcategory);
  45      } else {
  46          return (int)$DB->get_field_sql('SELECT min(id) from {user_info_category}');
  47      }
  48  }
  49  
  50  /**
  51   * Called on upgrade to create new profile fields based on the old user table columns
  52   * for icq, msn, aim, skype and url.
  53   *
  54   * @param string $social Social profile field.
  55   */
  56  function user_profile_social_moveto_profilefield($social) {
  57      global $DB;
  58  
  59      $users = $DB->get_records_select('user', "$social IS NOT NULL AND $social != ''");
  60      if (count($users)) {
  61          $profilefield = user_profile_social_create_profilefield($social);
  62          foreach ($users as $user) {
  63              $userinfodata = [
  64                  'userid' => $user->id,
  65                  'fieldid' => $profilefield->id,
  66                  'data' => $user->$social,
  67                  'dataformat' => 0
  68              ];
  69              $user->$social = '';
  70              $DB->update_record('user', $user);
  71              $DB->insert_record('user_info_data', $userinfodata);
  72          }
  73      }
  74  }
  75  
  76  /**
  77   * Create an new custom social profile field if it does not exist
  78   *
  79   * @param string $social Social profile field.
  80   * @return object DB record or social profield field.
  81   */
  82  function user_profile_social_create_profilefield($social) {
  83      global $DB, $CFG;
  84  
  85      $hiddenfields = explode(',', $CFG->hiddenuserfields);
  86      $confignames = [
  87          'url' => 'webpage',
  88          'icq' => 'icqnumber',
  89          'skype' => 'skypeid',
  90          'yahoo' => 'yahooid',
  91          'aim' => 'aimid',
  92          'msn' => 'msnid',
  93      ];
  94      $visible = (in_array($confignames[$social], $hiddenfields)) ? 3 : 2;
  95  
  96      $categoryid = user_profile_social_create_info_category();
  97  
  98      $newfield = (object)[
  99          'shortname' => $social,
 100          'name' => $social,
 101          'datatype' => 'social',
 102          'description' => '',
 103          'descriptionformat' => 1,
 104          'categoryid' => $categoryid,
 105          'required' => 0,
 106          'locked' => 0,
 107          'visible' => $visible,
 108          'forceunique' => 0,
 109          'signup' => 0,
 110          'defaultdata' => '',
 111          'defaultdataformat' => 0,
 112          'param1' => $social
 113      ];
 114  
 115      $profilefield = $DB->get_record_sql(
 116          'SELECT * FROM {user_info_field} WHERE datatype = :datatype AND ' .
 117          $DB->sql_compare_text('param1') . ' = ' . $DB->sql_compare_text(':social', 40),
 118          ['datatype' => 'social', 'social' => $social]);
 119  
 120      if (!$profilefield) {
 121  
 122          // Find a new unique shortname.
 123          $count = 0;
 124          $shortname = $newfield->shortname;
 125          while ($field = $DB->get_record('user_info_field', array('shortname' => $shortname))) {
 126              $count++;
 127              $shortname = $newfield->shortname . '_' . $count;
 128          }
 129          $newfield->shortname = $shortname;
 130  
 131          $profileclass = new profile_define_base();
 132          $profileclass->define_save($newfield);
 133          profile_reorder_fields();
 134  
 135          $profilefield = $DB->get_record_sql(
 136              'SELECT * FROM {user_info_field} WHERE datatype = :datatype AND ' .
 137              $DB->sql_compare_text('param1') . ' = ' . $DB->sql_compare_text(':social', 40),
 138              ['datatype' => 'social', 'social' => $social]);
 139      }
 140      if (!$profilefield) {
 141          throw new moodle_exception('upgradeerror', 'admin', 'could not create new social profile field');
 142      }
 143      return $profilefield;
 144  }
 145  
 146  /**
 147   * Update the module availability configuration for all course modules
 148   *
 149   */
 150  function user_profile_social_update_module_availability() {
 151      global $DB;
 152      // Use transaction to improve performance if there are many individual database updates.
 153      $transaction = $DB->start_delegated_transaction();
 154      // Query all the course_modules entries that have availability set.
 155      $rs = $DB->get_recordset_select('course_modules', 'availability IS NOT NULL', [], '', 'id, availability');
 156      foreach ($rs as $mod) {
 157          if (isset($mod->availability)) {
 158              $availability = json_decode($mod->availability);
 159              if (!is_null($availability)) {
 160                  user_profile_social_update_availability_structure($availability);
 161                  $newavailability = json_encode($availability);
 162                  if ($newavailability !== $mod->availability) {
 163                      $mod->availability = json_encode($availability);
 164                      $DB->update_record('course_modules', $mod);
 165                  }
 166              }
 167          }
 168      }
 169      $rs->close();
 170      $transaction->allow_commit();
 171  }
 172  
 173  /**
 174   * Loop through the availability info and change all move standard profile
 175   * fields for icq, skype, aim, yahoo, msn and url to be custom profile fields.
 176   * @param mixed $structure The availability object.
 177   */
 178  function user_profile_social_update_availability_structure(&$structure) {
 179      if (is_array($structure)) {
 180          foreach ($structure as $st) {
 181              user_profile_social_update_availability_structure($st);
 182          }
 183      }
 184      foreach ($structure as $key => $value) {
 185          if ($key === 'c' && is_array($value)) {
 186              user_profile_social_update_availability_structure($value);
 187          }
 188          if ($key === 'type' && $value === 'profile') {
 189              if (isset($structure->sf) && in_array($structure->sf,
 190                  ['icq', 'skype', 'aim', 'yahoo', 'msn', 'url'])) {
 191                  $structure->cf = $structure->sf;
 192                  unset($structure->sf);
 193              }
 194          }
 195      }
 196  }