Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 3.9.x will end* 10 May 2021 (12 months).
  • Bug fixes for security issues in 3.9.x will end* 8 May 2023 (36 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

Differences Between: [Versions 39 and 310] [Versions 39 and 311] [Versions 39 and 400] [Versions 39 and 401] [Versions 39 and 402] [Versions 39 and 403]

   1  <?php
   2  
   3  // This file is part of Moodle - http://moodle.org/
   4  //
   5  // Moodle is free software: you can redistribute it and/or modify
   6  // it under the terms of the GNU General Public License as published by
   7  // the Free Software Foundation, either version 3 of the License, or
   8  // (at your option) any later version.
   9  //
  10  // Moodle is distributed in the hope that it will be useful,
  11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13  // GNU General Public License for more details.
  14  //
  15  // You should have received a copy of the GNU General Public License
  16  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  17  
  18  /**
  19   * deprecatedlib.php - Old functions retained only for backward compatibility
  20   *
  21   * Old functions retained only for backward compatibility.  New code should not
  22   * use any of these functions.
  23   *
  24   * @package    core
  25   * @subpackage deprecated
  26   * @copyright  1999 onwards Martin Dougiamas  {@link http://moodle.com}
  27   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  28   * @deprecated
  29   */
  30  
  31  defined('MOODLE_INTERNAL') || die();
  32  
  33  /* === Functions that needs to be kept longer in deprecated lib than normal time period === */
  34  
  35  /**
  36   * Add an entry to the legacy log table.
  37   *
  38   * @deprecated since 2.7 use new events instead
  39   *
  40   * @param    int     $courseid  The course id
  41   * @param    string  $module  The module name  e.g. forum, journal, resource, course, user etc
  42   * @param    string  $action  'view', 'update', 'add' or 'delete', possibly followed by another word to clarify.
  43   * @param    string  $url     The file and parameters used to see the results of the action
  44   * @param    string  $info    Additional description information
  45   * @param    int     $cm      The course_module->id if there is one
  46   * @param    int|stdClass $user If log regards $user other than $USER
  47   * @return void
  48   */
  49  function add_to_log($courseid, $module, $action, $url='', $info='', $cm=0, $user=0) {
  50      debugging('add_to_log() has been deprecated, please rewrite your code to the new events API', DEBUG_DEVELOPER);
  51  
  52      // This is a nasty hack that allows us to put all the legacy stuff into legacy storage,
  53      // this way we may move all the legacy settings there too.
  54      $manager = get_log_manager();
  55      if (method_exists($manager, 'legacy_add_to_log')) {
  56          $manager->legacy_add_to_log($courseid, $module, $action, $url, $info, $cm, $user);
  57      }
  58  }
  59  
  60  /**
  61   * @deprecated since 2.6
  62   */
  63  function events_trigger() {
  64      throw new coding_exception('events_trigger() has been deprecated along with all Events 1 API in favour of Events 2 API.');
  65  }
  66  
  67  /**
  68   * List all core subsystems and their location
  69   *
  70   * This is a whitelist of components that are part of the core and their
  71   * language strings are defined in /lang/en/<<subsystem>>.php. If a given
  72   * plugin is not listed here and it does not have proper plugintype prefix,
  73   * then it is considered as course activity module.
  74   *
  75   * The location is optionally dirroot relative path. NULL means there is no special
  76   * directory for this subsystem. If the location is set, the subsystem's
  77   * renderer.php is expected to be there.
  78   *
  79   * @deprecated since 2.6, use core_component::get_core_subsystems()
  80   *
  81   * @param bool $fullpaths false means relative paths from dirroot, use true for performance reasons
  82   * @return array of (string)name => (string|null)location
  83   */
  84  function get_core_subsystems($fullpaths = false) {
  85      global $CFG;
  86  
  87      // NOTE: do not add any other debugging here, keep forever.
  88  
  89      $subsystems = core_component::get_core_subsystems();
  90  
  91      if ($fullpaths) {
  92          return $subsystems;
  93      }
  94  
  95      debugging('Short paths are deprecated when using get_core_subsystems(), please fix the code to use fullpaths instead.', DEBUG_DEVELOPER);
  96  
  97      $dlength = strlen($CFG->dirroot);
  98  
  99      foreach ($subsystems as $k => $v) {
 100          if ($v === null) {
 101              continue;
 102          }
 103          $subsystems[$k] = substr($v, $dlength+1);
 104      }
 105  
 106      return $subsystems;
 107  }
 108  
 109  /**
 110   * Lists all plugin types.
 111   *
 112   * @deprecated since 2.6, use core_component::get_plugin_types()
 113   *
 114   * @param bool $fullpaths false means relative paths from dirroot
 115   * @return array Array of strings - name=>location
 116   */
 117  function get_plugin_types($fullpaths = true) {
 118      global $CFG;
 119  
 120      // NOTE: do not add any other debugging here, keep forever.
 121  
 122      $types = core_component::get_plugin_types();
 123  
 124      if ($fullpaths) {
 125          return $types;
 126      }
 127  
 128      debugging('Short paths are deprecated when using get_plugin_types(), please fix the code to use fullpaths instead.', DEBUG_DEVELOPER);
 129  
 130      $dlength = strlen($CFG->dirroot);
 131  
 132      foreach ($types as $k => $v) {
 133          if ($k === 'theme') {
 134              $types[$k] = 'theme';
 135              continue;
 136          }
 137          $types[$k] = substr($v, $dlength+1);
 138      }
 139  
 140      return $types;
 141  }
 142  
 143  /**
 144   * Use when listing real plugins of one type.
 145   *
 146   * @deprecated since 2.6, use core_component::get_plugin_list()
 147   *
 148   * @param string $plugintype type of plugin
 149   * @return array name=>fulllocation pairs of plugins of given type
 150   */
 151  function get_plugin_list($plugintype) {
 152  
 153      // NOTE: do not add any other debugging here, keep forever.
 154  
 155      if ($plugintype === '') {
 156          $plugintype = 'mod';
 157      }
 158  
 159      return core_component::get_plugin_list($plugintype);
 160  }
 161  
 162  /**
 163   * Get a list of all the plugins of a given type that define a certain class
 164   * in a certain file. The plugin component names and class names are returned.
 165   *
 166   * @deprecated since 2.6, use core_component::get_plugin_list_with_class()
 167   *
 168   * @param string $plugintype the type of plugin, e.g. 'mod' or 'report'.
 169   * @param string $class the part of the name of the class after the
 170   *      frankenstyle prefix. e.g 'thing' if you are looking for classes with
 171   *      names like report_courselist_thing. If you are looking for classes with
 172   *      the same name as the plugin name (e.g. qtype_multichoice) then pass ''.
 173   * @param string $file the name of file within the plugin that defines the class.
 174   * @return array with frankenstyle plugin names as keys (e.g. 'report_courselist', 'mod_forum')
 175   *      and the class names as values (e.g. 'report_courselist_thing', 'qtype_multichoice').
 176   */
 177  function get_plugin_list_with_class($plugintype, $class, $file) {
 178  
 179      // NOTE: do not add any other debugging here, keep forever.
 180  
 181      return core_component::get_plugin_list_with_class($plugintype, $class, $file);
 182  }
 183  
 184  /**
 185   * Returns the exact absolute path to plugin directory.
 186   *
 187   * @deprecated since 2.6, use core_component::get_plugin_directory()
 188   *
 189   * @param string $plugintype type of plugin
 190   * @param string $name name of the plugin
 191   * @return string full path to plugin directory; NULL if not found
 192   */
 193  function get_plugin_directory($plugintype, $name) {
 194  
 195      // NOTE: do not add any other debugging here, keep forever.
 196  
 197      if ($plugintype === '') {
 198          $plugintype = 'mod';
 199      }
 200  
 201      return core_component::get_plugin_directory($plugintype, $name);
 202  }
 203  
 204  /**
 205   * Normalize the component name using the "frankenstyle" names.
 206   *
 207   * @deprecated since 2.6, use core_component::normalize_component()
 208   *
 209   * @param string $component
 210   * @return array two-items list of [(string)type, (string|null)name]
 211   */
 212  function normalize_component($component) {
 213  
 214      // NOTE: do not add any other debugging here, keep forever.
 215  
 216      return core_component::normalize_component($component);
 217  }
 218  
 219  /**
 220   * Return exact absolute path to a plugin directory.
 221   *
 222   * @deprecated since 2.6, use core_component::normalize_component()
 223   *
 224   * @param string $component name such as 'moodle', 'mod_forum'
 225   * @return string full path to component directory; NULL if not found
 226   */
 227  function get_component_directory($component) {
 228  
 229      // NOTE: do not add any other debugging here, keep forever.
 230  
 231      return core_component::get_component_directory($component);
 232  }
 233  
 234  /**
 235   * Get the context instance as an object. This function will create the
 236   * context instance if it does not exist yet.
 237   *
 238   * @deprecated since 2.2, use context_course::instance() or other relevant class instead
 239   * @todo This will be deleted in Moodle 2.8, refer MDL-34472
 240   * @param integer $contextlevel The context level, for example CONTEXT_COURSE, or CONTEXT_MODULE.
 241   * @param integer $instance The instance id. For $level = CONTEXT_COURSE, this would be $course->id,
 242   *      for $level = CONTEXT_MODULE, this would be $cm->id. And so on. Defaults to 0
 243   * @param int $strictness IGNORE_MISSING means compatible mode, false returned if record not found, debug message if more found;
 244   *      MUST_EXIST means throw exception if no record or multiple records found
 245   * @return context The context object.
 246   */
 247  function get_context_instance($contextlevel, $instance = 0, $strictness = IGNORE_MISSING) {
 248  
 249      debugging('get_context_instance() is deprecated, please use context_xxxx::instance() instead.', DEBUG_DEVELOPER);
 250  
 251      $instances = (array)$instance;
 252      $contexts = array();
 253  
 254      $classname = context_helper::get_class_for_level($contextlevel);
 255  
 256      // we do not load multiple contexts any more, PAGE should be responsible for any preloading
 257      foreach ($instances as $inst) {
 258          $contexts[$inst] = $classname::instance($inst, $strictness);
 259      }
 260  
 261      if (is_array($instance)) {
 262          return $contexts;
 263      } else {
 264          return $contexts[$instance];
 265      }
 266  }
 267  /* === End of long term deprecated api list === */
 268  
 269  /**
 270   * @deprecated since 2.7 - use new file picker instead
 271   */
 272  function clam_log_upload() {
 273      throw new coding_exception('clam_log_upload() can not be used any more, please use file picker instead');
 274  }
 275  
 276  /**
 277   * @deprecated since 2.7 - use new file picker instead
 278   */
 279  function clam_log_infected() {
 280      throw new coding_exception('clam_log_infected() can not be used any more, please use file picker instead');
 281  }
 282  
 283  /**
 284   * @deprecated since 2.7 - use new file picker instead
 285   */
 286  function clam_change_log() {
 287      throw new coding_exception('clam_change_log() can not be used any more, please use file picker instead');
 288  }
 289  
 290  /**
 291   * @deprecated since 2.7 - infected files are now deleted in file picker
 292   */
 293  function clam_replace_infected_file() {
 294      throw new coding_exception('clam_replace_infected_file() can not be used any more, please use file picker instead');
 295  }
 296  
 297  /**
 298   * @deprecated since 2.7
 299   */
 300  function clam_handle_infected_file() {
 301      throw new coding_exception('clam_handle_infected_file() can not be used any more, please use file picker instead');
 302  }
 303  
 304  /**
 305   * @deprecated since 2.7
 306   */
 307  function clam_scan_moodle_file() {
 308      throw new coding_exception('clam_scan_moodle_file() can not be used any more, please use file picker instead');
 309  }
 310  
 311  
 312  /**
 313   * @deprecated since 2.7 PHP 5.4.x should be always compatible.
 314   */
 315  function password_compat_not_supported() {
 316      throw new coding_exception('Do not use password_compat_not_supported() - bcrypt is now always available');
 317  }
 318  
 319  /**
 320   * @deprecated since 2.6
 321   */
 322  function session_get_instance() {
 323      throw new coding_exception('session_get_instance() is removed, use \core\session\manager instead');
 324  }
 325  
 326  /**
 327   * @deprecated since 2.6
 328   */
 329  function session_is_legacy() {
 330      throw new coding_exception('session_is_legacy() is removed, do not use any more');
 331  }
 332  
 333  /**
 334   * @deprecated since 2.6
 335   */
 336  function session_kill_all() {
 337      throw new coding_exception('session_kill_all() is removed, use \core\session\manager::kill_all_sessions() instead');
 338  }
 339  
 340  /**
 341   * @deprecated since 2.6
 342   */
 343  function session_touch() {
 344      throw new coding_exception('session_touch() is removed, use \core\session\manager::touch_session() instead');
 345  }
 346  
 347  /**
 348   * @deprecated since 2.6
 349   */
 350  function session_kill() {
 351      throw new coding_exception('session_kill() is removed, use \core\session\manager::kill_session() instead');
 352  }
 353  
 354  /**
 355   * @deprecated since 2.6
 356   */
 357  function session_kill_user() {
 358      throw new coding_exception('session_kill_user() is removed, use \core\session\manager::kill_user_sessions() instead');
 359  }
 360  
 361  /**
 362   * @deprecated since 2.6
 363   */
 364  function session_set_user() {
 365      throw new coding_exception('session_set_user() is removed, use \core\session\manager::set_user() instead');
 366  }
 367  
 368  /**
 369   * @deprecated since 2.6
 370   */
 371  function session_is_loggedinas() {
 372      throw new coding_exception('session_is_loggedinas() is removed, use \core\session\manager::is_loggedinas() instead');
 373  }
 374  
 375  /**
 376   * @deprecated since 2.6
 377   */
 378  function session_get_realuser() {
 379      throw new coding_exception('session_get_realuser() is removed, use \core\session\manager::get_realuser() instead');
 380  }
 381  
 382  /**
 383   * @deprecated since 2.6
 384   */
 385  function session_loginas() {
 386      throw new coding_exception('session_loginas() is removed, use \core\session\manager::loginas() instead');
 387  }
 388  
 389  /**
 390   * @deprecated since 2.6
 391   */
 392  function js_minify() {
 393      throw new coding_exception('js_minify() is removed, use core_minify::js_files() or core_minify::js() instead.');
 394  }
 395  
 396  /**
 397   * @deprecated since 2.6
 398   */
 399  function css_minify_css() {
 400      throw new coding_exception('css_minify_css() is removed, use core_minify::css_files() or core_minify::css() instead.');
 401  }
 402  
 403  // === Deprecated before 2.6.0 ===
 404  
 405  /**
 406   * @deprecated
 407   */
 408  function check_gd_version() {
 409      throw new coding_exception('check_gd_version() is removed, GD extension is always available now');
 410  }
 411  
 412  /**
 413   * @deprecated
 414   */
 415  function update_login_count() {
 416      throw new coding_exception('update_login_count() is removed, all calls need to be removed');
 417  }
 418  
 419  /**
 420   * @deprecated
 421   */
 422  function reset_login_count() {
 423      throw new coding_exception('reset_login_count() is removed, all calls need to be removed');
 424  }
 425  
 426  /**
 427   * @deprecated
 428   */
 429  function update_log_display_entry() {
 430  
 431      throw new coding_exception('The update_log_display_entry() is removed, please use db/log.php description file instead.');
 432  }
 433  
 434  /**
 435   * @deprecated use the text formatting in a standard way instead (http://docs.moodle.org/dev/Output_functions)
 436   *             this was abused mostly for embedding of attachments
 437   */
 438  function filter_text() {
 439      throw new coding_exception('filter_text() can not be used anymore, use format_text(), format_string() etc instead.');
 440  }
 441  
 442  /**
 443   * @deprecated Loginhttps is no longer supported
 444   */
 445  function httpsrequired() {
 446      throw new coding_exception('httpsrequired() can not be used any more. Loginhttps is no longer supported.');
 447  }
 448  
 449  /**
 450   * @deprecated since 3.1 - replacement legacy file API methods can be found on the moodle_url class, for example:
 451   * The moodle_url::make_legacyfile_url() method can be used to generate a legacy course file url. To generate
 452   * course module file.php url the moodle_url::make_file_url() should be used.
 453   */
 454  function get_file_url() {
 455      throw new coding_exception('get_file_url() can not be used anymore. Please use ' .
 456          'moodle_url factory methods instead.');
 457  }
 458  
 459  /**
 460   * @deprecated use get_enrolled_users($context) instead.
 461   */
 462  function get_course_participants() {
 463      throw new coding_exception('get_course_participants() can not be used any more, use get_enrolled_users() instead.');
 464  }
 465  
 466  /**
 467   * @deprecated use is_enrolled($context, $userid) instead.
 468   */
 469  function is_course_participant() {
 470      throw new coding_exception('is_course_participant() can not be used any more, use is_enrolled() instead.');
 471  }
 472  
 473  /**
 474   * @deprecated
 475   */
 476  function get_recent_enrolments() {
 477      throw new coding_exception('get_recent_enrolments() is removed as it returned inaccurate results.');
 478  }
 479  
 480  /**
 481   * @deprecated use clean_param($string, PARAM_FILE) instead.
 482   */
 483  function detect_munged_arguments() {
 484      throw new coding_exception('detect_munged_arguments() can not be used any more, please use clean_param(,PARAM_FILE) instead.');
 485  }
 486  
 487  
 488  /**
 489   * Unzip one zip file to a destination dir
 490   * Both parameters must be FULL paths
 491   * If destination isn't specified, it will be the
 492   * SAME directory where the zip file resides.
 493   *
 494   * @global object
 495   * @param string $zipfile The zip file to unzip
 496   * @param string $destination The location to unzip to
 497   * @param bool $showstatus_ignored Unused
 498   * @deprecated since 2.0 MDL-15919
 499   */
 500  function unzip_file($zipfile, $destination = '', $showstatus_ignored = true) {
 501      debugging(__FUNCTION__ . '() is deprecated. '
 502              . 'Please use the application/zip file_packer implementation instead.', DEBUG_DEVELOPER);
 503  
 504      // Extract everything from zipfile.
 505      $path_parts = pathinfo(cleardoubleslashes($zipfile));
 506      $zippath = $path_parts["dirname"];       //The path of the zip file
 507      $zipfilename = $path_parts["basename"];  //The name of the zip file
 508      $extension = $path_parts["extension"];    //The extension of the file
 509  
 510      //If no file, error
 511      if (empty($zipfilename)) {
 512          return false;
 513      }
 514  
 515      //If no extension, error
 516      if (empty($extension)) {
 517          return false;
 518      }
 519  
 520      //Clear $zipfile
 521      $zipfile = cleardoubleslashes($zipfile);
 522  
 523      //Check zipfile exists
 524      if (!file_exists($zipfile)) {
 525          return false;
 526      }
 527  
 528      //If no destination, passed let's go with the same directory
 529      if (empty($destination)) {
 530          $destination = $zippath;
 531      }
 532  
 533      //Clear $destination
 534      $destpath = rtrim(cleardoubleslashes($destination), "/");
 535  
 536      //Check destination path exists
 537      if (!is_dir($destpath)) {
 538          return false;
 539      }
 540  
 541      $packer = get_file_packer('application/zip');
 542  
 543      $result = $packer->extract_to_pathname($zipfile, $destpath);
 544  
 545      if ($result === false) {
 546          return false;
 547      }
 548  
 549      foreach ($result as $status) {
 550          if ($status !== true) {
 551              return false;
 552          }
 553      }
 554  
 555      return true;
 556  }
 557  
 558  /**
 559   * Zip an array of files/dirs to a destination zip file
 560   * Both parameters must be FULL paths to the files/dirs
 561   *
 562   * @global object
 563   * @param array $originalfiles Files to zip
 564   * @param string $destination The destination path
 565   * @return bool Outcome
 566   *
 567   * @deprecated since 2.0 MDL-15919
 568   */
 569  function zip_files($originalfiles, $destination) {
 570      debugging(__FUNCTION__ . '() is deprecated. '
 571              . 'Please use the application/zip file_packer implementation instead.', DEBUG_DEVELOPER);
 572  
 573      // Extract everything from destination.
 574      $path_parts = pathinfo(cleardoubleslashes($destination));
 575      $destpath = $path_parts["dirname"];       //The path of the zip file
 576      $destfilename = $path_parts["basename"];  //The name of the zip file
 577      $extension = $path_parts["extension"];    //The extension of the file
 578  
 579      //If no file, error
 580      if (empty($destfilename)) {
 581          return false;
 582      }
 583  
 584      //If no extension, add it
 585      if (empty($extension)) {
 586          $extension = 'zip';
 587          $destfilename = $destfilename.'.'.$extension;
 588      }
 589  
 590      //Check destination path exists
 591      if (!is_dir($destpath)) {
 592          return false;
 593      }
 594  
 595      //Check destination path is writable. TODO!!
 596  
 597      //Clean destination filename
 598      $destfilename = clean_filename($destfilename);
 599  
 600      //Now check and prepare every file
 601      $files = array();
 602      $origpath = NULL;
 603  
 604      foreach ($originalfiles as $file) {  //Iterate over each file
 605          //Check for every file
 606          $tempfile = cleardoubleslashes($file); // no doubleslashes!
 607          //Calculate the base path for all files if it isn't set
 608          if ($origpath === NULL) {
 609              $origpath = rtrim(cleardoubleslashes(dirname($tempfile)), "/");
 610          }
 611          //See if the file is readable
 612          if (!is_readable($tempfile)) {  //Is readable
 613              continue;
 614          }
 615          //See if the file/dir is in the same directory than the rest
 616          if (rtrim(cleardoubleslashes(dirname($tempfile)), "/") != $origpath) {
 617              continue;
 618          }
 619          //Add the file to the array
 620          $files[] = $tempfile;
 621      }
 622  
 623      $zipfiles = array();
 624      $start = strlen($origpath)+1;
 625      foreach($files as $file) {
 626          $zipfiles[substr($file, $start)] = $file;
 627      }
 628  
 629      $packer = get_file_packer('application/zip');
 630  
 631      return $packer->archive_to_pathname($zipfiles, $destpath . '/' . $destfilename);
 632  }
 633  
 634  /**
 635   * @deprecated use groups_get_all_groups() instead.
 636   */
 637  function mygroupid() {
 638      throw new coding_exception('mygroupid() can not be used any more, please use groups_get_all_groups() instead.');
 639  }
 640  
 641  /**
 642   * @deprecated since Moodle 2.0 MDL-14617 - please do not use this function any more.
 643   */
 644  function groupmode() {
 645      throw new coding_exception('groupmode() can not be used any more, please use groups_get_* instead.');
 646  }
 647  
 648  /**
 649   * @deprecated Since year 2006 - please do not use this function any more.
 650   */
 651  function set_current_group() {
 652      throw new coding_exception('set_current_group() can not be used anymore, please use $SESSION->currentgroup[$courseid] instead');
 653  }
 654  
 655  /**
 656   * @deprecated Since year 2006 - please do not use this function any more.
 657   */
 658  function get_current_group() {
 659      throw new coding_exception('get_current_group() can not be used any more, please use groups_get_* instead');
 660  }
 661  
 662  /**
 663   * @deprecated Since Moodle 2.8
 664   */
 665  function groups_filter_users_by_course_module_visible() {
 666      throw new coding_exception('groups_filter_users_by_course_module_visible() is removed. ' .
 667              'Replace with a call to \core_availability\info_module::filter_user_list(), ' .
 668              'which does basically the same thing but includes other restrictions such ' .
 669              'as profile restrictions.');
 670  }
 671  
 672  /**
 673   * @deprecated Since Moodle 2.8
 674   */
 675  function groups_course_module_visible() {
 676      throw new coding_exception('groups_course_module_visible() is removed, use $cm->uservisible to decide whether the current
 677          user can ' . 'access an activity.', DEBUG_DEVELOPER);
 678  }
 679  
 680  /**
 681   * @deprecated since 2.0
 682   */
 683  function error() {
 684      throw new coding_exception('notlocalisederrormessage', 'error', $link, $message, 'error() is a removed, please call
 685              print_error() instead of error()');
 686  }
 687  
 688  
 689  /**
 690   * @deprecated use $PAGE->theme->name instead.
 691   */
 692  function current_theme() {
 693      throw new coding_exception('current_theme() can not be used any more, please use $PAGE->theme->name instead');
 694  }
 695  
 696  /**
 697   * @deprecated
 698   */
 699  function formerr() {
 700      throw new coding_exception('formerr() is removed. Please change your code to use $OUTPUT->error_text($string).');
 701  }
 702  
 703  /**
 704   * @deprecated use $OUTPUT->skip_link_target() in instead.
 705   */
 706  function skip_main_destination() {
 707      throw new coding_exception('skip_main_destination() can not be used any more, please use $OUTPUT->skip_link_target() instead.');
 708  }
 709  
 710  /**
 711   * @deprecated use $OUTPUT->container() instead.
 712   */
 713  function print_container() {
 714      throw new coding_exception('print_container() can not be used any more. Please use $OUTPUT->container() instead.');
 715  }
 716  
 717  /**
 718   * @deprecated use $OUTPUT->container_start() instead.
 719   */
 720  function print_container_start() {
 721      throw new coding_exception('print_container_start() can not be used any more. Please use $OUTPUT->container_start() instead.');
 722  }
 723  
 724  /**
 725   * @deprecated use $OUTPUT->container_end() instead.
 726   */
 727  function print_container_end() {
 728      throw new coding_exception('print_container_end() can not be used any more. Please use $OUTPUT->container_end() instead.');
 729  }
 730  
 731  /**
 732   * @deprecated since Moodle 2.0 MDL-19077 - use $OUTPUT->notification instead.
 733   */
 734  function notify() {
 735      throw new coding_exception('notify() is removed, please use $OUTPUT->notification() instead');
 736  }
 737  
 738  /**
 739   * @deprecated use $OUTPUT->continue_button() instead.
 740   */
 741  function print_continue() {
 742      throw new coding_exception('print_continue() can not be used any more. Please use $OUTPUT->continue_button() instead.');
 743  }
 744  
 745  /**
 746   * @deprecated use $PAGE methods instead.
 747   */
 748  function print_header() {
 749  
 750      throw new coding_exception('print_header() can not be used any more. Please use $PAGE methods instead.');
 751  }
 752  
 753  /**
 754   * @deprecated use $PAGE methods instead.
 755   */
 756  function print_header_simple() {
 757  
 758      throw new coding_exception('print_header_simple() can not be used any more. Please use $PAGE methods instead.');
 759  }
 760  
 761  /**
 762   * @deprecated use $OUTPUT->block() instead.
 763   */
 764  function print_side_block() {
 765      throw new coding_exception('print_side_block() can not be used any more, please use $OUTPUT->block() instead.');
 766  }
 767  
 768  /**
 769   * Prints a basic textarea field.
 770   *
 771   * This was 'deprecated' in 2.0, but not properly (there was no alternative) so the
 772   * debugging message was commented out.
 773   *
 774   * @deprecated since Moodle 3.6
 775   *
 776   * When using this function, you should
 777   *
 778   * @global object
 779   * @param bool $unused No longer used.
 780   * @param int $rows Number of rows to display  (minimum of 10 when $height is non-null)
 781   * @param int $cols Number of columns to display (minimum of 65 when $width is non-null)
 782   * @param null $width (Deprecated) Width of the element; if a value is passed, the minimum value for $cols will be 65. Value is otherwise ignored.
 783   * @param null $height (Deprecated) Height of the element; if a value is passe, the minimum value for $rows will be 10. Value is otherwise ignored.
 784   * @param string $name Name to use for the textarea element.
 785   * @param string $value Initial content to display in the textarea.
 786   * @param int $obsolete deprecated
 787   * @param bool $return If false, will output string. If true, will return string value.
 788   * @param string $id CSS ID to add to the textarea element.
 789   * @return string|void depending on the value of $return
 790   */
 791  function print_textarea($unused, $rows, $cols, $width, $height, $name, $value='', $obsolete=0, $return=false, $id='') {
 792      /// $width and height are legacy fields and no longer used as pixels like they used to be.
 793      /// However, you can set them to zero to override the mincols and minrows values below.
 794  
 795      // Disabling because there is not yet a viable $OUTPUT option for cases when mforms can't be used
 796      debugging('print_textarea() is deprecated. Please use $OUTPUT->print_textarea() instead.', DEBUG_DEVELOPER);
 797  
 798      global $OUTPUT;
 799  
 800      $mincols = 65;
 801      $minrows = 10;
 802  
 803      if ($id === '') {
 804          $id = 'edit-'.$name;
 805      }
 806  
 807      if ($height && ($rows < $minrows)) {
 808          $rows = $minrows;
 809      }
 810      if ($width && ($cols < $mincols)) {
 811          $cols = $mincols;
 812      }
 813  
 814      $textarea = $OUTPUT->print_textarea($name, $id, $value, $rows, $cols);
 815      if ($return) {
 816          return $textarea;
 817      }
 818  
 819      echo $textarea;
 820  }
 821  
 822  /**
 823   * Returns an image of an up or down arrow, used for column sorting. To avoid unnecessary DB accesses, please
 824   * provide this function with the language strings for sortasc and sortdesc.
 825   *
 826   * @deprecated use $OUTPUT->arrow() instead.
 827   * @todo final deprecation of this function once MDL-45448 is resolved
 828   *
 829   * If no sort string is associated with the direction, an arrow with no alt text will be printed/returned.
 830   *
 831   * @global object
 832   * @param string $direction 'up' or 'down'
 833   * @param string $strsort The language string used for the alt attribute of this image
 834   * @param bool $return Whether to print directly or return the html string
 835   * @return string|void depending on $return
 836   *
 837   */
 838  function print_arrow($direction='up', $strsort=null, $return=false) {
 839      global $OUTPUT;
 840  
 841      debugging('print_arrow() is deprecated. Please use $OUTPUT->arrow() instead.', DEBUG_DEVELOPER);
 842  
 843      if (!in_array($direction, array('up', 'down', 'right', 'left', 'move'))) {
 844          return null;
 845      }
 846  
 847      $return = null;
 848  
 849      switch ($direction) {
 850          case 'up':
 851              $sortdir = 'asc';
 852              break;
 853          case 'down':
 854              $sortdir = 'desc';
 855              break;
 856          case 'move':
 857              $sortdir = 'asc';
 858              break;
 859          default:
 860              $sortdir = null;
 861              break;
 862      }
 863  
 864      // Prepare language string
 865      $strsort = '';
 866      if (empty($strsort) && !empty($sortdir)) {
 867          $strsort  = get_string('sort' . $sortdir, 'grades');
 868      }
 869  
 870      $return = ' ' . $OUTPUT->pix_icon('t/' . $direction, $strsort) . ' ';
 871  
 872      if ($return) {
 873          return $return;
 874      } else {
 875          echo $return;
 876      }
 877  }
 878  
 879  /**
 880   * @deprecated since Moodle 2.0
 881   */
 882  function choose_from_menu() {
 883      throw new coding_exception('choose_from_menu() is removed. Please change your code to use html_writer::select().');
 884  }
 885  
 886  /**
 887   * @deprecated use $OUTPUT->help_icon_scale($courseid, $scale) instead.
 888   */
 889  function print_scale_menu_helpbutton() {
 890      throw new coding_exception('print_scale_menu_helpbutton() can not be used any more. '.
 891          'Please use $OUTPUT->help_icon_scale($courseid, $scale) instead.');
 892  }
 893  
 894  /**
 895   * @deprecated use html_writer::checkbox() instead.
 896   */
 897  function print_checkbox() {
 898      throw new coding_exception('print_checkbox() can not be used any more. Please use html_writer::checkbox() instead.');
 899  }
 900  
 901  /**
 902   * @deprecated since Moodle 3.2
 903   */
 904  function update_module_button() {
 905      throw new coding_exception('update_module_button() can not be used anymore. Activity modules should ' .
 906          'not add the edit module button, the link is already available in the Administration block. Themes ' .
 907          'can choose to display the link in the buttons row consistently for all module types.');
 908  }
 909  
 910  /**
 911   * @deprecated use $OUTPUT->navbar() instead
 912   */
 913  function print_navigation () {
 914      throw new coding_exception('print_navigation() can not be used any more, please update use $OUTPUT->navbar() instead.');
 915  }
 916  
 917  /**
 918   * @deprecated Please use $PAGE->navabar methods instead.
 919   */
 920  function build_navigation() {
 921      throw new coding_exception('build_navigation() can not be used any more, please use $PAGE->navbar methods instead.');
 922  }
 923  
 924  /**
 925   * @deprecated not relevant with global navigation in Moodle 2.x+
 926   */
 927  function navmenu() {
 928      throw new coding_exception('navmenu() can not be used any more, it is no longer relevant with global navigation.');
 929  }
 930  
 931  /// CALENDAR MANAGEMENT  ////////////////////////////////////////////////////////////////
 932  
 933  
 934  /**
 935   * @deprecated please use calendar_event::create() instead.
 936   */
 937  function add_event() {
 938      throw new coding_exception('add_event() can not be used any more, please use calendar_event::create() instead.');
 939  }
 940  
 941  /**
 942   * @deprecated please calendar_event->update() instead.
 943   */
 944  function update_event() {
 945      throw new coding_exception('update_event() is removed, please use calendar_event->update() instead.');
 946  }
 947  
 948  /**
 949   * @deprecated please use calendar_event->delete() instead.
 950   */
 951  function delete_event() {
 952      throw new coding_exception('delete_event() can not be used any more, please use '.
 953          'calendar_event->delete() instead.');
 954  }
 955  
 956  /**
 957   * @deprecated please use calendar_event->toggle_visibility(false) instead.
 958   */
 959  function hide_event() {
 960      throw new coding_exception('hide_event() can not be used any more, please use '.
 961          'calendar_event->toggle_visibility(false) instead.');
 962  }
 963  
 964  /**
 965   * @deprecated please use calendar_event->toggle_visibility(true) instead.
 966   */
 967  function show_event() {
 968      throw new coding_exception('show_event() can not be used any more, please use '.
 969          'calendar_event->toggle_visibility(true) instead.');
 970  }
 971  
 972  /**
 973   * @deprecated since Moodle 2.2 use core_text::xxxx() instead.
 974   */
 975  function textlib_get_instance() {
 976      throw new coding_exception('textlib_get_instance() can not be used any more, please use '.
 977          'core_text::functioname() instead.');
 978  }
 979  
 980  /**
 981   * @deprecated since 2.4
 982   */
 983  function get_generic_section_name() {
 984      throw new coding_exception('get_generic_section_name() is deprecated. Please use appropriate functionality from class format_base');
 985  }
 986  
 987  /**
 988   * @deprecated since 2.4
 989   */
 990  function get_all_sections() {
 991      throw new coding_exception('get_all_sections() is removed. See phpdocs for this function');
 992  }
 993  
 994  /**
 995   * @deprecated since 2.4
 996   */
 997  function add_mod_to_section() {
 998      throw new coding_exception('Function add_mod_to_section() is removed, please use course_add_cm_to_section()');
 999  }
1000  
1001  /**
1002   * @deprecated since 2.4
1003   */
1004  function get_all_mods() {
1005      throw new coding_exception('Function get_all_mods() is removed. Use get_fast_modinfo() and get_module_types_names() instead. See phpdocs for details');
1006  }
1007  
1008  /**
1009   * @deprecated since 2.4
1010   */
1011  function get_course_section() {
1012      throw new coding_exception('Function get_course_section() is removed. Please use course_create_sections_if_missing() and get_fast_modinfo() instead.');
1013  }
1014  
1015  /**
1016   * @deprecated since 2.4
1017   */
1018  function format_weeks_get_section_dates() {
1019      throw new coding_exception('Function format_weeks_get_section_dates() is removed. It is not recommended to'.
1020              ' use it outside of format_weeks plugin');
1021  }
1022  
1023  /**
1024   * @deprecated since 2.5
1025   */
1026  function get_print_section_cm_text() {
1027      throw new coding_exception('Function get_print_section_cm_text() is removed. Please use '.
1028              'cm_info::get_formatted_content() and cm_info::get_formatted_name()');
1029  }
1030  
1031  /**
1032   * @deprecated since 2.5
1033   */
1034  function print_section_add_menus() {
1035      throw new coding_exception('Function print_section_add_menus() is removed. Please use course renderer '.
1036              'function course_section_add_cm_control()');
1037  }
1038  
1039  /**
1040   * @deprecated since 2.5. Please use:
1041   * $courserenderer = $PAGE->get_renderer('core', 'course');
1042   * $actions = course_get_cm_edit_actions($mod, $indent, $section);
1043   * return ' ' . $courserenderer->course_section_cm_edit_actions($actions);
1044   */
1045  function make_editing_buttons() {
1046      throw new coding_exception('Function make_editing_buttons() is removed, please see PHPdocs in '.
1047              'lib/deprecatedlib.php on how to replace it');
1048  }
1049  
1050  /**
1051   * @deprecated since 2.5
1052   */
1053  function print_section() {
1054      throw new coding_exception('Function print_section() is removed. Please use course renderer function '.
1055              'course_section_cm_list() instead.');
1056  }
1057  
1058  /**
1059   * @deprecated since 2.5
1060   */
1061  function print_overview() {
1062      throw new coding_exception('Function print_overview() is removed. Use block course_overview to display this information');
1063  }
1064  
1065  /**
1066   * @deprecated since 2.5
1067   */
1068  function print_recent_activity() {
1069      throw new coding_exception('Function print_recent_activity() is removed. It is not recommended to'.
1070              ' use it outside of block_recent_activity');
1071  }
1072  
1073  /**
1074   * @deprecated since 2.5
1075   */
1076  function delete_course_module() {
1077      throw new coding_exception('Function delete_course_module() is removed. Please use course_delete_module() instead.');
1078  }
1079  
1080  /**
1081   * @deprecated since 2.5
1082   */
1083  function update_category_button() {
1084      throw new coding_exception('Function update_category_button() is removed. Pages to view '.
1085              'and edit courses are now separate and no longer depend on editing mode.');
1086  }
1087  
1088  /**
1089   * @deprecated since 2.5
1090   */
1091  function make_categories_list() {
1092      throw new coding_exception('Global function make_categories_list() is removed. Please use '.
1093          'core_course_category::make_categories_list() and core_course_category::get_parents()');
1094  }
1095  
1096  /**
1097   * @deprecated since 2.5
1098   */
1099  function category_delete_move() {
1100      throw new coding_exception('Function category_delete_move() is removed. Please use ' .
1101          'core_course_category::delete_move() instead.');
1102  }
1103  
1104  /**
1105   * @deprecated since 2.5
1106   */
1107  function category_delete_full() {
1108      throw new coding_exception('Function category_delete_full() is removed. Please use ' .
1109          'core_course_category::delete_full() instead.');
1110  }
1111  
1112  /**
1113   * @deprecated since 2.5
1114   */
1115  function move_category() {
1116      throw new coding_exception('Function move_category() is removed. Please use core_course_category::change_parent() instead.');
1117  }
1118  
1119  /**
1120   * @deprecated since 2.5
1121   */
1122  function course_category_hide() {
1123      throw new coding_exception('Function course_category_hide() is removed. Please use core_course_category::hide() instead.');
1124  }
1125  
1126  /**
1127   * @deprecated since 2.5
1128   */
1129  function course_category_show() {
1130      throw new coding_exception('Function course_category_show() is removed. Please use core_course_category::show() instead.');
1131  }
1132  
1133  /**
1134   * @deprecated since 2.5. Please use core_course_category::get($catid, IGNORE_MISSING) or
1135   *     core_course_category::get($catid, MUST_EXIST).
1136   */
1137  function get_course_category() {
1138      throw new coding_exception('Function get_course_category() is removed. Please use core_course_category::get(), ' .
1139          'see phpdocs for more details');
1140  }
1141  
1142  /**
1143   * @deprecated since 2.5
1144   */
1145  function create_course_category() {
1146      throw new coding_exception('Function create_course_category() is removed. Please use core_course_category::create(), ' .
1147          'see phpdocs for more details');
1148  }
1149  
1150  /**
1151   * @deprecated since 2.5. Please use core_course_category::get() and core_course_category::get_children()
1152   */
1153  function get_all_subcategories() {
1154      throw new coding_exception('Function get_all_subcategories() is removed. Please use appropriate methods() '.
1155          'of core_course_category class. See phpdocs for more details');
1156  }
1157  
1158  /**
1159   * @deprecated since 2.5. Please use core_course_category::get($parentid)->get_children().
1160   */
1161  function get_child_categories() {
1162      throw new coding_exception('Function get_child_categories() is removed. Use core_course_category::get_children() or see ' .
1163          'phpdocs for more details.');
1164  }
1165  
1166  /**
1167   * @deprecated since 2.5
1168   */
1169  function get_categories() {
1170      throw new coding_exception('Function get_categories() is removed. Please use ' .
1171              'appropriate functions from class core_course_category');
1172  }
1173  
1174  /**
1175  * @deprecated since 2.5
1176  */
1177  function print_course_search() {
1178      throw new coding_exception('Function print_course_search() is removed, please use course renderer');
1179  }
1180  
1181  /**
1182   * @deprecated since 2.5
1183   */
1184  function print_my_moodle() {
1185      throw new coding_exception('Function print_my_moodle() is removed, please use course renderer ' .
1186              'function frontpage_my_courses()');
1187  }
1188  
1189  /**
1190   * @deprecated since 2.5
1191   */
1192  function print_remote_course() {
1193      throw new coding_exception('Function print_remote_course() is removed, please use course renderer');
1194  }
1195  
1196  /**
1197   * @deprecated since 2.5
1198   */
1199  function print_remote_host() {
1200      throw new coding_exception('Function print_remote_host() is removed, please use course renderer');
1201  }
1202  
1203  /**
1204   * @deprecated since 2.5
1205   */
1206  function print_whole_category_list() {
1207      throw new coding_exception('Function print_whole_category_list() is removed, please use course renderer');
1208  }
1209  
1210  /**
1211   * @deprecated since 2.5
1212   */
1213  function print_category_info() {
1214      throw new coding_exception('Function print_category_info() is removed, please use course renderer');
1215  }
1216  
1217  /**
1218   * @deprecated since 2.5
1219   */
1220  function get_course_category_tree() {
1221      throw new coding_exception('Function get_course_category_tree() is removed, please use course ' .
1222              'renderer or core_course_category class, see function phpdocs for more info');
1223  }
1224  
1225  /**
1226   * @deprecated since 2.5
1227   */
1228  function print_courses() {
1229      throw new coding_exception('Function print_courses() is removed, please use course renderer');
1230  }
1231  
1232  /**
1233   * @deprecated since 2.5
1234   */
1235  function print_course() {
1236      throw new coding_exception('Function print_course() is removed, please use course renderer');
1237  }
1238  
1239  /**
1240   * @deprecated since 2.5
1241   */
1242  function get_category_courses_array() {
1243      throw new coding_exception('Function get_category_courses_array() is removed, please use methods of ' .
1244          'core_course_category class');
1245  }
1246  
1247  /**
1248   * @deprecated since 2.5
1249   */
1250  function get_category_courses_array_recursively() {
1251      throw new coding_exception('Function get_category_courses_array_recursively() is removed, please use ' .
1252          'methods of core_course_category class', DEBUG_DEVELOPER);
1253  }
1254  
1255  /**
1256   * @deprecated since Moodle 2.5 MDL-27814 - please do not use this function any more.
1257   */
1258  function blog_get_context_url() {
1259      throw new coding_exception('Function  blog_get_context_url() is removed, getting params from context is not reliable for blogs.');
1260  }
1261  
1262  /**
1263   * @deprecated since 2.5
1264   */
1265  function get_courses_wmanagers() {
1266      throw new coding_exception('Function get_courses_wmanagers() is removed, please use ' .
1267          'core_course_category::get_courses()');
1268  }
1269  
1270  /**
1271   * @deprecated since 2.5
1272   */
1273  function convert_tree_to_html() {
1274      throw new coding_exception('Function convert_tree_to_html() is removed. Consider using class tabtree and core_renderer::render_tabtree()');
1275  }
1276  
1277  /**
1278   * @deprecated since 2.5
1279   */
1280  function convert_tabrows_to_tree() {
1281      throw new coding_exception('Function convert_tabrows_to_tree() is removed. Consider using class tabtree');
1282  }
1283  
1284  /**
1285   * @deprecated since 2.5 - do not use, the textrotate.js will work it out automatically
1286   */
1287  function can_use_rotated_text() {
1288      debugging('can_use_rotated_text() is removed. JS feature detection is used automatically.');
1289  }
1290  
1291  /**
1292   * @deprecated since Moodle 2.2 MDL-35009 - please do not use this function any more.
1293   */
1294  function get_context_instance_by_id() {
1295      throw new coding_exception('get_context_instance_by_id() is now removed, please use context::instance_by_id($id) instead.');
1296  }
1297  
1298  /**
1299   * Returns system context or null if can not be created yet.
1300   *
1301   * @see context_system::instance()
1302   * @deprecated since 2.2
1303   * @param bool $cache use caching
1304   * @return context system context (null if context table not created yet)
1305   */
1306  function get_system_context($cache = true) {
1307      debugging('get_system_context() is deprecated, please use context_system::instance() instead.', DEBUG_DEVELOPER);
1308      return context_system::instance(0, IGNORE_MISSING, $cache);
1309  }
1310  
1311  /**
1312   * @deprecated since 2.2, use $context->get_parent_context_ids() instead
1313   */
1314  function get_parent_contexts() {
1315      throw new coding_exception('get_parent_contexts() is removed, please use $context->get_parent_context_ids() instead.');
1316  }
1317  
1318  /**
1319   * @deprecated since Moodle 2.2
1320   */
1321  function get_parent_contextid() {
1322      throw new coding_exception('get_parent_contextid() is removed, please use $context->get_parent_context() instead.');
1323  }
1324  
1325  /**
1326   * @deprecated since 2.2
1327   */
1328  function get_child_contexts() {
1329      throw new coding_exception('get_child_contexts() is removed, please use $context->get_child_contexts() instead.');
1330  }
1331  
1332  /**
1333   * @deprecated since 2.2
1334   */
1335  function create_contexts() {
1336      throw new coding_exception('create_contexts() is removed, please use context_helper::create_instances() instead.');
1337  }
1338  
1339  /**
1340   * @deprecated since 2.2
1341   */
1342  function cleanup_contexts() {
1343      throw new coding_exception('cleanup_contexts() is removed, please use context_helper::cleanup_instances() instead.');
1344  }
1345  
1346  /**
1347   * @deprecated since 2.2
1348   */
1349  function build_context_path() {
1350      throw new coding_exception('build_context_path() is removed, please use context_helper::build_all_paths() instead.');
1351  }
1352  
1353  /**
1354   * @deprecated since 2.2
1355   */
1356  function rebuild_contexts() {
1357      throw new coding_exception('rebuild_contexts() is removed, please use $context->reset_paths(true) instead.');
1358  }
1359  
1360  /**
1361   * @deprecated since Moodle 2.2
1362   */
1363  function preload_course_contexts() {
1364      throw new coding_exception('preload_course_contexts() is removed, please use context_helper::preload_course() instead.');
1365  }
1366  
1367  /**
1368   * @deprecated since Moodle 2.2
1369   */
1370  function context_moved() {
1371      throw new coding_exception('context_moved() is removed, please use context::update_moved() instead.');
1372  }
1373  
1374  /**
1375   * @deprecated since 2.2
1376   */
1377  function fetch_context_capabilities() {
1378      throw new coding_exception('fetch_context_capabilities() is removed, please use $context->get_capabilities() instead.');
1379  }
1380  
1381  /**
1382   * @deprecated since 2.2
1383   */
1384  function context_instance_preload() {
1385      throw new coding_exception('context_instance_preload() is removed, please use context_helper::preload_from_record() instead.');
1386  }
1387  
1388  /**
1389   * @deprecated since 2.2
1390   */
1391  function get_contextlevel_name() {
1392      throw new coding_exception('get_contextlevel_name() is removed, please use context_helper::get_level_name() instead.');
1393  }
1394  
1395  /**
1396   * @deprecated since 2.2
1397   */
1398  function print_context_name() {
1399      throw new coding_exception('print_context_name() is removed, please use $context->get_context_name() instead.');
1400  }
1401  
1402  /**
1403   * @deprecated since 2.2, use $context->mark_dirty() instead
1404   */
1405  function mark_context_dirty() {
1406      throw new coding_exception('mark_context_dirty() is removed, please use $context->mark_dirty() instead.');
1407  }
1408  
1409  /**
1410   * @deprecated since Moodle 2.2
1411   */
1412  function delete_context() {
1413      throw new coding_exception('delete_context() is removed, please use context_helper::delete_instance() ' .
1414              'or $context->delete_content() instead.');
1415  }
1416  
1417  /**
1418   * @deprecated since 2.2
1419   */
1420  function get_context_url() {
1421      throw new coding_exception('get_context_url() is removed, please use $context->get_url() instead.');
1422  }
1423  
1424  /**
1425   * @deprecated since 2.2
1426   */
1427  function get_course_context() {
1428      throw new coding_exception('get_course_context() is removed, please use $context->get_course_context(true) instead.');
1429  }
1430  
1431  /**
1432   * @deprecated since 2.2
1433   */
1434  function get_user_courses_bycap() {
1435      throw new coding_exception('get_user_courses_bycap() is removed, please use enrol_get_users_courses() instead.');
1436  }
1437  
1438  /**
1439   * @deprecated since Moodle 2.2
1440   */
1441  function get_role_context_caps() {
1442      throw new coding_exception('get_role_context_caps() is removed, it is really slow. Don\'t use it.');
1443  }
1444  
1445  /**
1446   * @deprecated since 2.2
1447   */
1448  function get_courseid_from_context() {
1449      throw new coding_exception('get_courseid_from_context() is removed, please use $context->get_course_context(false) instead.');
1450  }
1451  
1452  /**
1453   * @deprecated since 2.2
1454   */
1455  function context_instance_preload_sql() {
1456      throw new coding_exception('context_instance_preload_sql() is removed, please use context_helper::get_preload_record_columns_sql() instead.');
1457  }
1458  
1459  /**
1460   * @deprecated since 2.2
1461   */
1462  function get_related_contexts_string() {
1463      throw new coding_exception('get_related_contexts_string() is removed, please use $context->get_parent_context_ids(true) instead.');
1464  }
1465  
1466  /**
1467   * @deprecated since 2.6
1468   */
1469  function get_plugin_list_with_file() {
1470      throw new coding_exception('get_plugin_list_with_file() is removed, please use core_component::get_plugin_list_with_file() instead.');
1471  }
1472  
1473  /**
1474   * @deprecated since 2.6
1475   */
1476  function check_browser_operating_system() {
1477      throw new coding_exception('check_browser_operating_system is removed, please update your code to use core_useragent instead.');
1478  }
1479  
1480  /**
1481   * @deprecated since 2.6
1482   */
1483  function check_browser_version() {
1484      throw new coding_exception('check_browser_version is removed, please update your code to use core_useragent instead.');
1485  }
1486  
1487  /**
1488   * @deprecated since 2.6
1489   */
1490  function get_device_type() {
1491      throw new coding_exception('get_device_type is removed, please update your code to use core_useragent instead.');
1492  }
1493  
1494  /**
1495   * @deprecated since 2.6
1496   */
1497  function get_device_type_list() {
1498      throw new coding_exception('get_device_type_list is removed, please update your code to use core_useragent instead.');
1499  }
1500  
1501  /**
1502   * @deprecated since 2.6
1503   */
1504  function get_selected_theme_for_device_type() {
1505      throw new coding_exception('get_selected_theme_for_device_type is removed, please update your code to use core_useragent instead.');
1506  }
1507  
1508  /**
1509   * @deprecated since 2.6
1510   */
1511  function get_device_cfg_var_name() {
1512      throw new coding_exception('get_device_cfg_var_name is removed, please update your code to use core_useragent instead.');
1513  }
1514  
1515  /**
1516   * @deprecated since 2.6
1517   */
1518  function set_user_device_type() {
1519      throw new coding_exception('set_user_device_type is removed, please update your code to use core_useragent instead.');
1520  }
1521  
1522  /**
1523   * @deprecated since 2.6
1524   */
1525  function get_user_device_type() {
1526      throw new coding_exception('get_user_device_type is removed, please update your code to use core_useragent instead.');
1527  }
1528  
1529  /**
1530   * @deprecated since 2.6
1531   */
1532  function get_browser_version_classes() {
1533      throw new coding_exception('get_browser_version_classes is removed, please update your code to use core_useragent instead.');
1534  }
1535  
1536  /**
1537   * @deprecated since Moodle 2.6
1538   */
1539  function generate_email_supportuser() {
1540      throw new coding_exception('generate_email_supportuser is removed, please use core_user::get_support_user');
1541  }
1542  
1543  /**
1544   * @deprecated since Moodle 2.6
1545   */
1546  function badges_get_issued_badge_info() {
1547      throw new coding_exception('Function badges_get_issued_badge_info() is removed. Please use core_badges_assertion class and methods to generate badge assertion.');
1548  }
1549  
1550  /**
1551   * @deprecated since 2.6
1552   */
1553  function can_use_html_editor() {
1554      throw new coding_exception('can_use_html_editor is removed, please update your code to assume it returns true.');
1555  }
1556  
1557  
1558  /**
1559   * @deprecated since Moodle 2.7, use {@link user_count_login_failures()} instead.
1560   */
1561  function count_login_failures() {
1562      throw new coding_exception('count_login_failures() can not be used any more, please use user_count_login_failures().');
1563  }
1564  
1565  /**
1566   * @deprecated since 2.7 MDL-33099/MDL-44088 - please do not use this function any more.
1567   */
1568  function ajaxenabled() {
1569      throw new coding_exception('ajaxenabled() can not be used anymore. Update your code to work with JS at all times.');
1570  }
1571  
1572  /**
1573   * @deprecated Since Moodle 2.7 MDL-44070
1574   */
1575  function coursemodule_visible_for_user() {
1576      throw new coding_exception('coursemodule_visible_for_user() can not be used any more,
1577              please use \core_availability\info_module::is_user_visible()');
1578  }
1579  
1580  /**
1581   * @deprecated since Moodle 2.8 MDL-36014, MDL-35618 this functionality is removed
1582   */
1583  function enrol_cohort_get_cohorts() {
1584      throw new coding_exception('Function enrol_cohort_get_cohorts() is removed, use '.
1585          'cohort_get_available_cohorts() instead');
1586  }
1587  
1588  /**
1589   * @deprecated since Moodle 2.8 MDL-36014 please use cohort_can_view_cohort()
1590   */
1591  function enrol_cohort_can_view_cohort() {
1592      throw new coding_exception('Function enrol_cohort_can_view_cohort() is removed, use cohort_can_view_cohort() instead');
1593  }
1594  
1595  /**
1596   * @deprecated since Moodle 2.8 MDL-36014 use cohort_get_available_cohorts() instead
1597   */
1598  function cohort_get_visible_list() {
1599      throw new coding_exception('Function cohort_get_visible_list() is removed. Please use function cohort_get_available_cohorts() ".
1600          "that correctly checks capabilities.');
1601  }
1602  
1603  /**
1604   * @deprecated since Moodle 2.8 MDL-35618 this functionality is removed
1605   */
1606  function enrol_cohort_enrol_all_users() {
1607      throw new coding_exception('enrol_cohort_enrol_all_users() is removed. This functionality is moved to enrol_manual.');
1608  }
1609  
1610  /**
1611   * @deprecated since Moodle 2.8 MDL-35618 this functionality is removed
1612   */
1613  function enrol_cohort_search_cohorts() {
1614      throw new coding_exception('enrol_cohort_search_cohorts() is removed. This functionality is moved to enrol_manual.');
1615  }
1616  
1617  /* === Apis deprecated in since Moodle 2.9 === */
1618  
1619  /**
1620   * @deprecated since Moodle 2.9 MDL-49371 - please do not use this function any more.
1621   */
1622  function message_current_user_is_involved() {
1623      throw new coding_exception('message_current_user_is_involved() can not be used any more.');
1624  }
1625  
1626  /**
1627   * @deprecated since Moodle 2.9 MDL-45898 - please do not use this function any more.
1628   */
1629  function profile_display_badges() {
1630      throw new coding_exception('profile_display_badges() can not be used any more.');
1631  }
1632  
1633  /**
1634   * @deprecated since Moodle 2.9 MDL-45774 - Please do not use this function any more.
1635   */
1636  function useredit_shared_definition_preferences() {
1637      throw new coding_exception('useredit_shared_definition_preferences() can not be used any more.');
1638  }
1639  
1640  
1641  /**
1642   * @deprecated since Moodle 2.9
1643   */
1644  function calendar_normalize_tz() {
1645      throw new coding_exception('calendar_normalize_tz() can not be used any more, please use core_date::normalise_timezone() instead.');
1646  }
1647  
1648  /**
1649   * @deprecated since Moodle 2.9
1650   */
1651  function get_user_timezone_offset() {
1652      throw new coding_exception('get_user_timezone_offset() can not be used any more, please use standard PHP DateTimeZone class instead');
1653  
1654  }
1655  
1656  /**
1657   * @deprecated since Moodle 2.9
1658   */
1659  function get_timezone_offset() {
1660      throw new coding_exception('get_timezone_offset() can not be used any more, please use standard PHP DateTimeZone class instead');
1661  }
1662  
1663  /**
1664   * @deprecated since Moodle 2.9
1665   */
1666  function get_list_of_timezones() {
1667      throw new coding_exception('get_list_of_timezones() can not be used any more, please use core_date::get_list_of_timezones() instead');
1668  }
1669  
1670  /**
1671   * @deprecated since Moodle 2.9
1672   */
1673  function update_timezone_records() {
1674      throw new coding_exception('update_timezone_records() can not be used any more, please use standard PHP DateTime class instead');
1675  }
1676  
1677  /**
1678   * @deprecated since Moodle 2.9
1679   */
1680  function calculate_user_dst_table() {
1681      throw new coding_exception('calculate_user_dst_table() can not be used any more, please use standard PHP DateTime class instead');
1682  }
1683  
1684  /**
1685   * @deprecated since Moodle 2.9
1686   */
1687  function dst_changes_for_year() {
1688      throw new coding_exception('dst_changes_for_year() can not be used any more, please use standard DateTime class instead');
1689  }
1690  
1691  /**
1692   * @deprecated since Moodle 2.9
1693   */
1694  function get_timezone_record() {
1695      throw new coding_exception('get_timezone_record() can not be used any more, please use standard PHP DateTime class instead');
1696  }
1697  
1698  /* === Apis deprecated since Moodle 3.0 === */
1699  /**
1700   * @deprecated since Moodle 3.0 MDL-49360 - please do not use this function any more.
1701   */
1702  function get_referer() {
1703      throw new coding_exception('get_referer() can not be used any more. Please use get_local_referer() instead.');
1704  }
1705  
1706  /**
1707   * @deprecated since Moodle 3.0 use \core_useragent::is_web_crawler instead.
1708   */
1709  function is_web_crawler() {
1710      throw new coding_exception('is_web_crawler() can not be used any more. Please use core_useragent::is_web_crawler() instead.');
1711  }
1712  
1713  /**
1714   * @deprecated since Moodle 3.0 MDL-50287 - please do not use this function any more.
1715   */
1716  function completion_cron() {
1717      throw new coding_exception('completion_cron() can not be used any more. Functionality has been moved to scheduled tasks.');
1718  }
1719  
1720  /**
1721   * @deprecated since 3.0
1722   */
1723  function coursetag_get_tags() {
1724      throw new coding_exception('Function coursetag_get_tags() can not be used any more. ' .
1725              'Userid is no longer used for tagging courses.');
1726  }
1727  
1728  /**
1729   * @deprecated since 3.0
1730   */
1731  function coursetag_get_all_tags() {
1732      throw new coding_exception('Function coursetag_get_all_tags() can not be used any more. Userid is no ' .
1733          'longer used for tagging courses.');
1734  }
1735  
1736  /**
1737   * @deprecated since 3.0
1738   */
1739  function coursetag_get_jscript() {
1740      throw new coding_exception('Function coursetag_get_jscript() can not be used any more and is obsolete.');
1741  }
1742  
1743  /**
1744   * @deprecated since 3.0
1745   */
1746  function coursetag_get_jscript_links() {
1747      throw new coding_exception('Function coursetag_get_jscript_links() can not be used any more and is obsolete.');
1748  }
1749  
1750  /**
1751   * @deprecated since 3.0
1752   */
1753  function coursetag_get_records() {
1754      throw new coding_exception('Function coursetag_get_records() can not be used any more. ' .
1755              'Userid is no longer used for tagging courses.');
1756  }
1757  
1758  /**
1759   * @deprecated since 3.0
1760   */
1761  function coursetag_store_keywords() {
1762      throw new coding_exception('Function coursetag_store_keywords() can not be used any more. ' .
1763              'Userid is no longer used for tagging courses.');
1764  }
1765  
1766  /**
1767   * @deprecated since 3.0
1768   */
1769  function coursetag_delete_keyword() {
1770      throw new coding_exception('Function coursetag_delete_keyword() can not be used any more. ' .
1771              'Userid is no longer used for tagging courses.');
1772  }
1773  
1774  /**
1775   * @deprecated since 3.0
1776   */
1777  function coursetag_get_tagged_courses() {
1778      throw new coding_exception('Function coursetag_get_tagged_courses() can not be used any more. ' .
1779              'Userid is no longer used for tagging courses.');
1780  }
1781  
1782  /**
1783   * @deprecated since 3.0
1784   */
1785  function coursetag_delete_course_tags() {
1786      throw new coding_exception('Function coursetag_delete_course_tags() is deprecated. ' .
1787              'Use core_tag_tag::remove_all_item_tags().');
1788  }
1789  
1790  /**
1791   * @deprecated since 3.1. Use core_tag_tag::get($tagid)->update() instead
1792   */
1793  function tag_type_set() {
1794      throw new coding_exception('tag_type_set() can not be used anymore. Please use ' .
1795          'core_tag_tag::get($tagid)->update().');
1796  }
1797  
1798  /**
1799   * @deprecated since 3.1. Use core_tag_tag::get($tagid)->update() instead
1800   */
1801  function tag_description_set() {
1802      throw new coding_exception('tag_description_set() can not be used anymore. Please use ' .
1803          'core_tag_tag::get($tagid)->update().');
1804  }
1805  
1806  /**
1807   * @deprecated since 3.1. Use core_tag_tag::get_item_tags() instead
1808   */
1809  function tag_get_tags() {
1810      throw new coding_exception('tag_get_tags() can not be used anymore. Please use ' .
1811          'core_tag_tag::get_item_tags().');
1812  }
1813  
1814  /**
1815   * @deprecated since 3.1
1816   */
1817  function tag_get_tags_array() {
1818      throw new coding_exception('tag_get_tags_array() can not be used anymore. Please use ' .
1819          'core_tag_tag::get_item_tags_array().');
1820  }
1821  
1822  /**
1823   * @deprecated since 3.1. Use core_tag_tag::get_item_tags_array() or $OUTPUT->tag_list(core_tag_tag::get_item_tags())
1824   */
1825  function tag_get_tags_csv() {
1826      throw new coding_exception('tag_get_tags_csv() can not be used anymore. Please use ' .
1827          'core_tag_tag::get_item_tags_array() or $OUTPUT->tag_list(core_tag_tag::get_item_tags()).');
1828  }
1829  
1830  /**
1831   * @deprecated since 3.1. Use core_tag_tag::get_item_tags() instead
1832   */
1833  function tag_get_tags_ids() {
1834      throw new coding_exception('tag_get_tags_ids() can not be used anymore. Please consider using ' .
1835          'core_tag_tag::get_item_tags() or similar methods.');
1836  }
1837  
1838  /**
1839   * @deprecated since 3.1. Use core_tag_tag::get_by_name() or core_tag_tag::get_by_name_bulk()
1840   */
1841  function tag_get_id() {
1842      throw new coding_exception('tag_get_id() can not be used anymore. Please use ' .
1843          'core_tag_tag::get_by_name() or core_tag_tag::get_by_name_bulk()');
1844  }
1845  
1846  /**
1847   * @deprecated since 3.1. Use core_tag_tag::get($tagid)->update() instead
1848   */
1849  function tag_rename() {
1850      throw new coding_exception('tag_rename() can not be used anymore. Please use ' .
1851          'core_tag_tag::get($tagid)->update()');
1852  }
1853  
1854  /**
1855   * @deprecated since 3.1. Use core_tag_tag::remove_item_tag() instead
1856   */
1857  function tag_delete_instance() {
1858      throw new coding_exception('tag_delete_instance() can not be used anymore. Please use ' .
1859          'core_tag_tag::remove_item_tag()');
1860  }
1861  
1862  /**
1863   * @deprecated since 3.1. Use core_tag_tag::get_by_name()->get_tagged_items() instead
1864   */
1865  function tag_find_records() {
1866      throw new coding_exception('tag_find_records() can not be used anymore. Please use ' .
1867          'core_tag_tag::get_by_name()->get_tagged_items()');
1868  }
1869  
1870  /**
1871   * @deprecated since 3.1
1872   */
1873  function tag_add() {
1874      throw new coding_exception('tag_add() can not be used anymore. You can use ' .
1875          'core_tag_tag::create_if_missing(), however it should not be necessary since tags are ' .
1876          'created automatically when assigned to items');
1877  }
1878  
1879  /**
1880   * @deprecated since 3.1. Use core_tag_tag::set_item_tags() or core_tag_tag::add_item_tag() instead
1881   */
1882  function tag_assign() {
1883      throw new coding_exception('tag_assign() can not be used anymore. Please use ' .
1884          'core_tag_tag::set_item_tags() or core_tag_tag::add_item_tag() instead. Tag instance ' .
1885          'ordering should not be set manually');
1886  }
1887  
1888  /**
1889   * @deprecated since 3.1. Use core_tag_tag::get($tagid)->count_tagged_items() instead
1890   */
1891  function tag_record_count() {
1892      throw new coding_exception('tag_record_count() can not be used anymore. Please use ' .
1893          'core_tag_tag::get($tagid)->count_tagged_items().');
1894  }
1895  
1896  /**
1897   * @deprecated since 3.1. Use core_tag_tag::get($tagid)->is_item_tagged_with() instead
1898   */
1899  function tag_record_tagged_with() {
1900      throw new coding_exception('tag_record_tagged_with() can not be used anymore. Please use ' .
1901          'core_tag_tag::get($tagid)->is_item_tagged_with().');
1902  }
1903  
1904  /**
1905   * @deprecated since 3.1. Use core_tag_tag::get($tagid)->flag() instead
1906   */
1907  function tag_set_flag() {
1908      throw new coding_exception('tag_set_flag() can not be used anymore. Please use ' .
1909          'core_tag_tag::get($tagid)->flag()');
1910  }
1911  
1912  /**
1913   * @deprecated since 3.1. Use core_tag_tag::get($tagid)->reset_flag() instead
1914   */
1915  function tag_unset_flag() {
1916      throw new coding_exception('tag_unset_flag() can not be used anymore. Please use ' .
1917          'core_tag_tag::get($tagid)->reset_flag()');
1918  }
1919  
1920  /**
1921   * @deprecated since 3.1
1922   */
1923  function tag_print_cloud() {
1924      throw new coding_exception('tag_print_cloud() can not be used anymore. Please use ' .
1925          'core_tag_collection::get_tag_cloud(), templateable core_tag\output\tagcloud and ' .
1926          'template core_tag/tagcloud.');
1927  }
1928  
1929  /**
1930   * @deprecated since 3.0
1931   */
1932  function tag_autocomplete() {
1933      throw new coding_exception('tag_autocomplete() can not be used anymore. New form ' .
1934          'element "tags" does proper autocomplete.');
1935  }
1936  
1937  /**
1938   * @deprecated since 3.1
1939   */
1940  function tag_print_description_box() {
1941      throw new coding_exception('tag_print_description_box() can not be used anymore. ' .
1942          'See core_tag_renderer for similar code');
1943  }
1944  
1945  /**
1946   * @deprecated since 3.1
1947   */
1948  function tag_print_management_box() {
1949      throw new coding_exception('tag_print_management_box() can not be used anymore. ' .
1950          'See core_tag_renderer for similar code');
1951  }
1952  
1953  /**
1954   * @deprecated since 3.1
1955   */
1956  function tag_print_search_box() {
1957      throw new coding_exception('tag_print_search_box() can not be used anymore. ' .
1958          'See core_tag_renderer for similar code');
1959  }
1960  
1961  /**
1962   * @deprecated since 3.1
1963   */
1964  function tag_print_search_results() {
1965      throw new coding_exception('tag_print_search_results() can not be used anymore. ' .
1966          'In /tag/search.php the search results are printed using the core_tag/tagcloud template.');
1967  }
1968  
1969  /**
1970   * @deprecated since 3.1
1971   */
1972  function tag_print_tagged_users_table() {
1973      throw new coding_exception('tag_print_tagged_users_table() can not be used anymore. ' .
1974          'See core_user_renderer for similar code');
1975  }
1976  
1977  /**
1978   * @deprecated since 3.1
1979   */
1980  function tag_print_user_box() {
1981      throw new coding_exception('tag_print_user_box() can not be used anymore. ' .
1982          'See core_user_renderer for similar code');
1983  }
1984  
1985  /**
1986   * @deprecated since 3.1
1987   */
1988  function tag_print_user_list() {
1989      throw new coding_exception('tag_print_user_list() can not be used anymore. ' .
1990          'See core_user_renderer for similar code');
1991  }
1992  
1993  /**
1994   * @deprecated since 3.1
1995   */
1996  function tag_display_name() {
1997      throw new coding_exception('tag_display_name() can not be used anymore. Please use ' .
1998          'core_tag_tag::make_display_name().');
1999  
2000  }
2001  
2002  /**
2003   * @deprecated since 3.1
2004   */
2005  function tag_normalize() {
2006      throw new coding_exception('tag_normalize() can not be used anymore. Please use ' .
2007          'core_tag_tag::normalize().');
2008  }
2009  
2010  /**
2011   * @deprecated since 3.1
2012   */
2013  function tag_get_related_tags_csv() {
2014      throw new coding_exception('tag_get_related_tags_csv() can not be used anymore. Please ' .
2015          'consider looping through array or using $OUTPUT->tag_list(core_tag_tag::get_item_tags()).');
2016  }
2017  
2018  /**
2019   * @deprecated since 3.1
2020   */
2021  function tag_set() {
2022      throw new coding_exception('tag_set() can not be used anymore. Please use ' .
2023          'core_tag_tag::set_item_tags().');
2024  }
2025  
2026  /**
2027   * @deprecated since 3.1
2028   */
2029  function tag_set_add() {
2030      throw new coding_exception('tag_set_add() can not be used anymore. Please use ' .
2031          'core_tag_tag::add_item_tag().');
2032  }
2033  
2034  /**
2035   * @deprecated since 3.1
2036   */
2037  function tag_set_delete() {
2038      throw new coding_exception('tag_set_delete() can not be used anymore. Please use ' .
2039          'core_tag_tag::remove_item_tag().');
2040  }
2041  
2042  /**
2043   * @deprecated since 3.1
2044   */
2045  function tag_get() {
2046      throw new coding_exception('tag_get() can not be used anymore. Please use ' .
2047          'core_tag_tag::get() or core_tag_tag::get_by_name().');
2048  }
2049  
2050  /**
2051   * @deprecated since 3.1
2052   */
2053  function tag_get_related_tags() {
2054      throw new coding_exception('tag_get_related_tags() can not be used anymore. Please use ' .
2055          'core_tag_tag::get_correlated_tags(), core_tag_tag::get_related_tags() or ' .
2056          'core_tag_tag::get_manual_related_tags().');
2057  }
2058  
2059  /**
2060   * @deprecated since 3.1
2061   */
2062  function tag_delete() {
2063      throw new coding_exception('tag_delete() can not be used anymore. Please use ' .
2064          'core_tag_tag::delete_tags().');
2065  }
2066  
2067  /**
2068   * @deprecated since 3.1
2069   */
2070  function tag_delete_instances() {
2071      throw new coding_exception('tag_delete_instances() can not be used anymore. Please use ' .
2072          'core_tag_tag::delete_instances().');
2073  }
2074  
2075  /**
2076   * @deprecated since 3.1
2077   */
2078  function tag_cleanup() {
2079      throw new coding_exception('tag_cleanup() can not be used anymore. Please use ' .
2080          '\core\task\tag_cron_task::cleanup().');
2081  }
2082  
2083  /**
2084   * @deprecated since 3.1
2085   */
2086  function tag_bulk_delete_instances() {
2087      throw new coding_exception('tag_bulk_delete_instances() can not be used anymore. Please use ' .
2088          '\core\task\tag_cron_task::bulk_delete_instances().');
2089  
2090  }
2091  
2092  /**
2093   * @deprecated since 3.1
2094   */
2095  function tag_compute_correlations() {
2096      throw new coding_exception('tag_compute_correlations() can not be used anymore. Please use ' .
2097          'use \core\task\tag_cron_task::compute_correlations().');
2098  }
2099  
2100  /**
2101   * @deprecated since 3.1
2102   */
2103  function tag_process_computed_correlation() {
2104      throw new coding_exception('tag_process_computed_correlation() can not be used anymore. Please use ' .
2105          'use \core\task\tag_cron_task::process_computed_correlation().');
2106  }
2107  
2108  /**
2109   * @deprecated since 3.1
2110   */
2111  function tag_cron() {
2112      throw new coding_exception('tag_cron() can not be used anymore. Please use ' .
2113          'use \core\task\tag_cron_task::execute().');
2114  }
2115  
2116  /**
2117   * @deprecated since 3.1
2118   */
2119  function tag_find_tags() {
2120      throw new coding_exception('tag_find_tags() can not be used anymore.');
2121  }
2122  
2123  /**
2124   * @deprecated since 3.1
2125   */
2126  function tag_get_name() {
2127      throw new coding_exception('tag_get_name() can not be used anymore.');
2128  }
2129  
2130  /**
2131   * @deprecated since 3.1
2132   */
2133  function tag_get_correlated() {
2134      throw new coding_exception('tag_get_correlated() can not be used anymore. Please use ' .
2135          'use core_tag_tag::get_correlated_tags().');
2136  
2137  }
2138  
2139  /**
2140   * @deprecated since 3.1
2141   */
2142  function tag_cloud_sort() {
2143      throw new coding_exception('tag_cloud_sort() can not be used anymore. Similar method can ' .
2144          'be found in core_tag_collection::cloud_sort().');
2145  }
2146  
2147  /**
2148   * @deprecated since Moodle 3.1
2149   */
2150  function events_load_def() {
2151      throw new coding_exception('events_load_def() has been deprecated along with all Events 1 API in favour of Events 2 API.');
2152  
2153  }
2154  
2155  /**
2156   * @deprecated since Moodle 3.1
2157   */
2158  function events_queue_handler() {
2159      throw new coding_exception('events_queue_handler() has been deprecated along with all Events 1 API in favour of Events 2 API.');
2160  }
2161  
2162  /**
2163   * @deprecated since Moodle 3.1
2164   */
2165  function events_dispatch() {
2166      throw new coding_exception('events_dispatch() has been deprecated along with all Events 1 API in favour of Events 2 API.');
2167  }
2168  
2169  /**
2170   * @deprecated since Moodle 3.1
2171   */
2172  function events_process_queued_handler() {
2173      throw new coding_exception(
2174          'events_process_queued_handler() has been deprecated along with all Events 1 API in favour of Events 2 API.'
2175      );
2176  }
2177  
2178  /**
2179   * @deprecated since Moodle 3.1
2180   */
2181  function events_update_definition() {
2182      throw new coding_exception(
2183          'events_update_definition has been deprecated along with all Events 1 API in favour of Events 2 API.'
2184      );
2185  }
2186  
2187  /**
2188   * @deprecated since Moodle 3.1
2189   */
2190  function events_cron() {
2191      throw new coding_exception('events_cron() has been deprecated along with all Events 1 API in favour of Events 2 API.');
2192  }
2193  
2194  /**
2195   * @deprecated since Moodle 3.1
2196   */
2197  function events_trigger_legacy() {
2198      throw new coding_exception('events_trigger_legacy() has been deprecated along with all Events 1 API in favour of Events 2 API.');
2199  }
2200  
2201  /**
2202   * @deprecated since Moodle 3.1
2203   */
2204  function events_is_registered() {
2205      throw new coding_exception('events_is_registered() has been deprecated along with all Events 1 API in favour of Events 2 API.');
2206  }
2207  
2208  /**
2209   * @deprecated since Moodle 3.1
2210   */
2211  function events_pending_count() {
2212      throw new coding_exception('events_pending_count() has been deprecated along with all Events 1 API in favour of Events 2 API.');
2213  }
2214  
2215  /**
2216   * @deprecated since Moodle 3.0 - this is a part of clamav plugin now.
2217   */
2218  function clam_message_admins() {
2219      throw new coding_exception('clam_message_admins() can not be used anymore. Please use ' .
2220          'message_admins() method of \antivirus_clamav\scanner class.');
2221  }
2222  
2223  /**
2224   * @deprecated since Moodle 3.0 - this is a part of clamav plugin now.
2225   */
2226  function get_clam_error_code() {
2227      throw new coding_exception('get_clam_error_code() can not be used anymore. Please use ' .
2228          'get_clam_error_code() method of \antivirus_clamav\scanner class.');
2229  }
2230  
2231  /**
2232   * @deprecated since 3.1
2233   */
2234  function course_get_cm_rename_action() {
2235      throw new coding_exception('course_get_cm_rename_action() can not be used anymore. Please use ' .
2236          'inplace_editable https://docs.moodle.org/dev/Inplace_editable.');
2237  
2238  }
2239  
2240  /**
2241   * @deprecated since Moodle 3.1
2242   */
2243  function course_scale_used() {
2244      throw new coding_exception('course_scale_used() can not be used anymore. Plugins can ' .
2245          'implement <modname>_scale_used_anywhere, all implementations of <modname>_scale_used are now ignored');
2246  }
2247  
2248  /**
2249   * @deprecated since Moodle 3.1
2250   */
2251  function site_scale_used() {
2252      throw new coding_exception('site_scale_used() can not be used anymore. Plugins can implement ' .
2253          '<modname>_scale_used_anywhere, all implementations of <modname>_scale_used are now ignored');
2254  }
2255  
2256  /**
2257   * @deprecated since Moodle 3.1. Use external_api::external_function_info().
2258   */
2259  function external_function_info() {
2260      throw new coding_exception('external_function_info() can not be used any'.
2261          'more. Please use external_api::external_function_info() instead.');
2262  }
2263  
2264  /**
2265   * @deprecated since Moodle 3.2
2266   * @see csv_import_reader::load_csv_content()
2267   */
2268  function get_records_csv() {
2269      throw new coding_exception('get_records_csv() can not be used anymore. Please use ' .
2270          'lib/csvlib.class.php csv_import_reader() instead.');
2271  }
2272  
2273  /**
2274   * @deprecated since Moodle 3.2
2275   * @see download_as_dataformat (lib/dataformatlib.php)
2276   */
2277  function put_records_csv() {
2278      throw new coding_exception('put_records_csv() can not be used anymore. Please use ' .
2279          'lib/dataformatlib.php download_as_dataformat() instead.');
2280  }
2281  
2282  /**
2283   * @deprecated since Moodle 3.2
2284   */
2285  function css_is_colour() {
2286      throw new coding_exception('css_is_colour() can not be used anymore.');
2287  }
2288  
2289  /**
2290   * @deprecated since Moodle 3.2
2291   */
2292  function css_is_width() {
2293      throw new coding_exception('css_is_width() can not be used anymore.');
2294  }
2295  
2296  /**
2297   * @deprecated since Moodle 3.2
2298   */
2299  function css_sort_by_count() {
2300      throw new coding_exception('css_sort_by_count() can not be used anymore.');
2301  }
2302  
2303  /**
2304   * @deprecated since Moodle 3.2
2305   */
2306  function message_get_course_contexts() {
2307      throw new coding_exception('message_get_course_contexts() can not be used anymore.');
2308  }
2309  
2310  /**
2311   * @deprecated since Moodle 3.2
2312   */
2313  function message_remove_url_params() {
2314      throw new coding_exception('message_remove_url_params() can not be used anymore.');
2315  }
2316  
2317  /**
2318   * @deprecated since Moodle 3.2
2319   */
2320  function message_count_messages() {
2321      throw new coding_exception('message_count_messages() can not be used anymore.');
2322  }
2323  
2324  /**
2325   * @deprecated since Moodle 3.2
2326   */
2327  function message_count_blocked_users() {
2328      throw new coding_exception('message_count_blocked_users() can not be used anymore. Please use ' .
2329          '\core_message\api::count_blocked_users() instead.');
2330  }
2331  
2332  /**
2333   * @deprecated since Moodle 3.2
2334   */
2335  function message_contact_link() {
2336      throw new coding_exception('message_contact_link() can not be used anymore.');
2337  }
2338  
2339  /**
2340   * @deprecated since Moodle 3.2
2341   */
2342  function message_get_recent_notifications() {
2343      throw new coding_exception('message_get_recent_notifications() can not be used anymore.');
2344  }
2345  
2346  /**
2347   * @deprecated since Moodle 3.2
2348   */
2349  function message_history_link() {
2350      throw new coding_exception('message_history_link() can not be used anymore.');
2351  }
2352  
2353  /**
2354   * @deprecated since Moodle 3.2
2355   */
2356  function message_search() {
2357      throw new coding_exception('message_search() can not be used anymore.');
2358  }
2359  
2360  /**
2361   * @deprecated since Moodle 3.2
2362   */
2363  function message_shorten_message() {
2364      throw new coding_exception('message_shorten_message() can not be used anymore.');
2365  }
2366  
2367  /**
2368   * @deprecated since Moodle 3.2
2369   */
2370  function message_get_fragment() {
2371      throw new coding_exception('message_get_fragment() can not be used anymore.');
2372  }
2373  
2374  /**
2375   * @deprecated since Moodle 3.2
2376   */
2377  function message_get_history() {
2378      throw new coding_exception('message_get_history() can not be used anymore.');
2379  }
2380  
2381  /**
2382   * @deprecated since Moodle 3.2
2383   */
2384  function message_get_contact_add_remove_link() {
2385      throw new coding_exception('message_get_contact_add_remove_link() can not be used anymore.');
2386  }
2387  
2388  /**
2389   * @deprecated since Moodle 3.2
2390   */
2391  function message_get_contact_block_link() {
2392      throw new coding_exception('message_get_contact_block_link() can not be used anymore.');
2393  }
2394  
2395  /**
2396   * @deprecated since Moodle 3.2
2397   */
2398  function message_mark_messages_read() {
2399      throw new coding_exception('message_mark_messages_read() can not be used anymore. Please use ' .
2400          '\core_message\api::mark_all_messages_as_read() instead.');
2401  }
2402  
2403  /**
2404   * @deprecated since Moodle 3.2
2405   */
2406  function message_page_type_list() {
2407      throw new coding_exception('message_page_type_list() can not be used anymore.');
2408  }
2409  
2410  /**
2411   * @deprecated since Moodle 3.2
2412   */
2413  function message_can_post_message() {
2414      throw new coding_exception('message_can_post_message() can not be used anymore. Please use ' .
2415          '\core_message\api::can_send_message() instead.');
2416  }
2417  
2418  /**
2419   * @deprecated since Moodle 3.2
2420   */
2421  function message_is_user_non_contact_blocked() {
2422      throw new coding_exception('message_is_user_non_contact_blocked() can not be used anymore. Please use ' .
2423          '\core_message\api::is_user_non_contact_blocked() instead.');
2424  }
2425  
2426  /**
2427   * @deprecated since Moodle 3.2
2428   */
2429  function message_is_user_blocked() {
2430      throw new coding_exception('message_is_user_blocked() can not be used anymore. Please use ' .
2431          '\core_message\api::is_user_blocked() instead.');
2432  }
2433  
2434  /**
2435   * @deprecated since Moodle 3.2
2436   */
2437  function print_log() {
2438      throw new coding_exception('print_log() can not be used anymore. Please use the ' .
2439          'report_log framework instead.');
2440  }
2441  
2442  /**
2443   * @deprecated since Moodle 3.2
2444   */
2445  function print_mnet_log() {
2446      throw new coding_exception('print_mnet_log() can not be used anymore. Please use the ' .
2447          'report_log framework instead.');
2448  }
2449  
2450  /**
2451   * @deprecated since Moodle 3.2
2452   */
2453  function print_log_csv() {
2454      throw new coding_exception('print_log_csv() can not be used anymore. Please use the ' .
2455          'report_log framework instead.');
2456  }
2457  
2458  /**
2459   * @deprecated since Moodle 3.2
2460   */
2461  function print_log_xls() {
2462      throw new coding_exception('print_log_xls() can not be used anymore. Please use the ' .
2463          'report_log framework instead.');
2464  }
2465  
2466  /**
2467   * @deprecated since Moodle 3.2
2468   */
2469  function print_log_ods() {
2470      throw new coding_exception('print_log_ods() can not be used anymore. Please use the ' .
2471          'report_log framework instead.');
2472  }
2473  
2474  /**
2475   * @deprecated since Moodle 3.2
2476   */
2477  function build_logs_array() {
2478      throw new coding_exception('build_logs_array() can not be used anymore. Please use the ' .
2479          'report_log framework instead.');
2480  }
2481  
2482  /**
2483   * @deprecated since Moodle 3.2
2484   */
2485  function get_logs_usercourse() {
2486      throw new coding_exception('get_logs_usercourse() can not be used anymore. Please use the ' .
2487          'report_log framework instead.');
2488  }
2489  
2490  /**
2491   * @deprecated since Moodle 3.2
2492   */
2493  function get_logs_userday() {
2494      throw new coding_exception('get_logs_userday() can not be used anymore. Please use the ' .
2495          'report_log framework instead.');
2496  }
2497  
2498  /**
2499   * @deprecated since Moodle 3.2
2500   */
2501  function get_logs() {
2502      throw new coding_exception('get_logs() can not be used anymore. Please use the ' .
2503          'report_log framework instead.');
2504  }
2505  
2506  /**
2507   * @deprecated since Moodle 3.2
2508   */
2509  function prevent_form_autofill_password() {
2510      throw new coding_exception('prevent_form_autofill_password() can not be used anymore.');
2511  }
2512  
2513  /**
2514   * @deprecated since Moodle 3.3 MDL-57370
2515   */
2516  function message_get_recent_conversations($userorid, $limitfrom = 0, $limitto = 100) {
2517      throw new coding_exception('message_get_recent_conversations() can not be used any more. ' .
2518          'Please use \core_message\api::get_conversations() instead.', DEBUG_DEVELOPER);
2519  }
2520  
2521  /**
2522   * @deprecated since Moodle 3.2
2523   */
2524  function calendar_preferences_button() {
2525      throw new coding_exception('calendar_preferences_button() can not be used anymore. The calendar ' .
2526          'preferences are now linked to the user preferences page.');
2527  }
2528  
2529  /**
2530   * @deprecated since 3.3
2531   */
2532  function calendar_wday_name() {
2533      throw new coding_exception('Function calendar_wday_name() is removed and no longer used in core.');
2534  }
2535  
2536  /**
2537   * @deprecated since 3.3
2538   */
2539  function calendar_get_block_upcoming() {
2540      throw new coding_exception('Function calendar_get_block_upcoming() is removed,' .
2541          'Please see block_calendar_upcoming::get_content() for the correct API usage.');
2542  }
2543  
2544  /**
2545   * @deprecated since 3.3
2546   */
2547  function calendar_print_month_selector() {
2548      throw new coding_exception('Function calendar_print_month_selector() is removed and can no longer used in core.');
2549  }
2550  
2551  /**
2552   * @deprecated since 3.3
2553   */
2554  function calendar_cron() {
2555      throw new coding_exception('Function calendar_cron() is removed. Please use the core\task\calendar_cron_task instead.');
2556  }
2557  
2558  /**
2559   * @deprecated since Moodle 3.4 and removed immediately. MDL-49398.
2560   */
2561  function load_course_context() {
2562      throw new coding_exception('load_course_context() is removed. Do not use private functions or data structures.');
2563  }
2564  
2565  /**
2566   * @deprecated since Moodle 3.4 and removed immediately. MDL-49398.
2567   */
2568  function load_role_access_by_context() {
2569      throw new coding_exception('load_role_access_by_context() is removed. Do not use private functions or data structures.');
2570  }
2571  
2572  /**
2573   * @deprecated since Moodle 3.4 and removed immediately. MDL-49398.
2574   */
2575  function dedupe_user_access() {
2576      throw new coding_exception('dedupe_user_access() is removed. Do not use private functions or data structures.');
2577  }
2578  
2579  /**
2580   * @deprecated since Moodle 3.4. MDL-49398.
2581   */
2582  function get_user_access_sitewide() {
2583      throw new coding_exception('get_user_access_sitewide() is removed. Do not use private functions or data structures.');
2584  }
2585  
2586  /**
2587   * @deprecated since Moodle 3.4. MDL-59333
2588   */
2589  function calendar_get_mini() {
2590      throw new coding_exception('calendar_get_mini() has been removed. Please update your code to use calendar_get_view.');
2591  }
2592  
2593  /**
2594   * @deprecated since Moodle 3.4. MDL-59333
2595   */
2596  function calendar_get_upcoming() {
2597      throw new coding_exception('calendar_get_upcoming() has been removed. ' .
2598              'Please see block_calendar_upcoming::get_content() for the correct API usage.');
2599  }
2600  
2601  /**
2602   * @deprecated since Moodle 3.4. MDL-50666
2603   */
2604  function allow_override() {
2605      throw new coding_exception('allow_override() has been removed. Please update your code to use core_role_set_override_allowed.');
2606  }
2607  
2608  /**
2609   * @deprecated since Moodle 3.4. MDL-50666
2610   */
2611  function allow_assign() {
2612      throw new coding_exception('allow_assign() has been removed. Please update your code to use core_role_set_assign_allowed.');
2613  }
2614  
2615  /**
2616   * @deprecated since Moodle 3.4. MDL-50666
2617   */
2618  function allow_switch() {
2619      throw new coding_exception('allow_switch() has been removed. Please update your code to use core_role_set_switch_allowed.');
2620  }
2621  
2622  /**
2623   * @deprecated since Moodle 3.5. MDL-61132
2624   */
2625  function question_add_tops() {
2626      throw new coding_exception(
2627          'question_add_tops() has been removed. You may want to pass $top = true to get_categories_for_contexts().'
2628      );
2629  }
2630  
2631  /**
2632   * @deprecated since Moodle 3.5. MDL-61132
2633   */
2634  function question_is_only_toplevel_category_in_context() {
2635      throw new coding_exception('question_is_only_toplevel_category_in_context() has been removed. '
2636              . 'Please update your code to use question_is_only_child_of_top_category_in_context() instead.');
2637  }
2638  
2639  /**
2640   * @deprecated since Moodle 3.5
2641   */
2642  function message_move_userfrom_unread2read() {
2643      throw new coding_exception('message_move_userfrom_unread2read() has been removed.');
2644  }
2645  
2646  /**
2647   * @deprecated since Moodle 3.5
2648   */
2649  function message_get_blocked_users() {
2650      throw new coding_exception(
2651          'message_get_blocked_users() has been removed, please use \core_message\api::get_blocked_users() instead.'
2652      );
2653  }
2654  
2655  /**
2656   * @deprecated since Moodle 3.5
2657   */
2658  function message_get_contacts() {
2659      throw new coding_exception('message_get_contacts() has been removed.');
2660  }
2661  
2662  /**
2663   * @deprecated since Moodle 3.5
2664   */
2665  function message_mark_message_read() {
2666      throw new coding_exception('message_mark_message_read() has been removed, please use \core_message\api::mark_message_as_read()
2667          or \core_message\api::mark_notification_as_read().');
2668  }
2669  
2670  /**
2671   * @deprecated since Moodle 3.5
2672   */
2673  function message_can_delete_message() {
2674      throw new coding_exception(
2675          'message_can_delete_message() has been removed, please use \core_message\api::can_delete_message() instead.'
2676      );
2677  }
2678  
2679  /**
2680   * @deprecated since Moodle 3.5
2681   */
2682  function message_delete_message() {
2683      throw new coding_exception(
2684          'message_delete_message() has been removed, please use \core_message\api::delete_message() instead.'
2685      );
2686  }
2687  
2688  /**
2689   * Get all of the allowed types for all of the courses and groups
2690   * the logged in user belongs to.
2691   *
2692   * The returned array will optionally have 5 keys:
2693   *      'user' : true if the logged in user can create user events
2694   *      'site' : true if the logged in user can create site events
2695   *      'category' : array of course categories that the user can create events for
2696   *      'course' : array of courses that the user can create events for
2697   *      'group': array of groups that the user can create events for
2698   *      'groupcourses' : array of courses that the groups belong to (can
2699   *                       be different from the list in 'course'.
2700   * @deprecated since 3.6
2701   * @return array The array of allowed types.
2702   */
2703  function calendar_get_all_allowed_types() {
2704      debugging('calendar_get_all_allowed_types() is deprecated. Please use calendar_get_allowed_types() instead.',
2705          DEBUG_DEVELOPER);
2706  
2707      global $CFG, $USER, $DB;
2708  
2709      require_once($CFG->libdir . '/enrollib.php');
2710  
2711      $types = [];
2712  
2713      $allowed = new stdClass();
2714  
2715      calendar_get_allowed_types($allowed);
2716  
2717      if ($allowed->user) {
2718          $types['user'] = true;
2719      }
2720  
2721      if ($allowed->site) {
2722          $types['site'] = true;
2723      }
2724  
2725      if (core_course_category::has_manage_capability_on_any()) {
2726          $types['category'] = core_course_category::make_categories_list('moodle/category:manage');
2727      }
2728  
2729      // This function warms the context cache for the course so the calls
2730      // to load the course context in calendar_get_allowed_types don't result
2731      // in additional DB queries.
2732      $courses = calendar_get_default_courses(null, 'id, groupmode, groupmodeforce', true);
2733  
2734      // We want to pre-fetch all of the groups for each course in a single
2735      // query to avoid calendar_get_allowed_types from hitting the DB for
2736      // each separate course.
2737      $groups = groups_get_all_groups_for_courses($courses);
2738  
2739      foreach ($courses as $course) {
2740          $coursegroups = isset($groups[$course->id]) ? $groups[$course->id] : null;
2741          calendar_get_allowed_types($allowed, $course, $coursegroups);
2742  
2743          if (!empty($allowed->courses)) {
2744              $types['course'][$course->id] = $course;
2745          }
2746  
2747          if (!empty($allowed->groups)) {
2748              $types['groupcourses'][$course->id] = $course;
2749  
2750              if (!isset($types['group'])) {
2751                  $types['group'] = array_values($allowed->groups);
2752              } else {
2753                  $types['group'] = array_merge($types['group'], array_values($allowed->groups));
2754              }
2755          }
2756      }
2757  
2758      return $types;
2759  }
2760  
2761  /**
2762   * Gets array of all groups in a set of course.
2763   *
2764   * @category group
2765   * @param array $courses Array of course objects or course ids.
2766   * @return array Array of groups indexed by course id.
2767   */
2768  function groups_get_all_groups_for_courses($courses) {
2769      global $DB;
2770  
2771      if (empty($courses)) {
2772          return [];
2773      }
2774  
2775      $groups = [];
2776      $courseids = [];
2777  
2778      foreach ($courses as $course) {
2779          $courseid = is_object($course) ? $course->id : $course;
2780          $groups[$courseid] = [];
2781          $courseids[] = $courseid;
2782      }
2783  
2784      $groupfields = [
2785          'g.id as gid',
2786          'g.courseid',
2787          'g.idnumber',
2788          'g.name',
2789          'g.description',
2790          'g.descriptionformat',
2791          'g.enrolmentkey',
2792          'g.picture',
2793          'g.hidepicture',
2794          'g.timecreated',
2795          'g.timemodified'
2796      ];
2797  
2798      $groupsmembersfields = [
2799          'gm.id as gmid',
2800          'gm.groupid',
2801          'gm.userid',
2802          'gm.timeadded',
2803          'gm.component',
2804          'gm.itemid'
2805      ];
2806  
2807      $concatidsql = $DB->sql_concat_join("'-'", ['g.id', 'COALESCE(gm.id, 0)']) . ' AS uniqid';
2808      list($courseidsql, $params) = $DB->get_in_or_equal($courseids);
2809      $groupfieldssql = implode(',', $groupfields);
2810      $groupmembersfieldssql = implode(',', $groupsmembersfields);
2811      $sql = "SELECT {$concatidsql}, {$groupfieldssql}, {$groupmembersfieldssql}
2812                FROM {groups} g
2813           LEFT JOIN {groups_members} gm
2814                  ON gm.groupid = g.id
2815               WHERE g.courseid {$courseidsql}";
2816  
2817      $results = $DB->get_records_sql($sql, $params);
2818  
2819      // The results will come back as a flat dataset thanks to the left
2820      // join so we will need to do some post processing to blow it out
2821      // into a more usable data structure.
2822      //
2823      // This loop will extract the distinct groups from the result set
2824      // and add it's list of members to the object as a property called
2825      // 'members'. Then each group will be added to the result set indexed
2826      // by it's course id.
2827      //
2828      // The resulting data structure for $groups should be:
2829      // $groups = [
2830      //      '1' = [
2831      //          '1' => (object) [
2832      //              'id' => 1,
2833      //              <rest of group properties>
2834      //              'members' => [
2835      //                  '1' => (object) [
2836      //                      <group member properties>
2837      //                  ],
2838      //                  '2' => (object) [
2839      //                      <group member properties>
2840      //                  ]
2841      //              ]
2842      //          ],
2843      //          '2' => (object) [
2844      //              'id' => 2,
2845      //              <rest of group properties>
2846      //              'members' => [
2847      //                  '1' => (object) [
2848      //                      <group member properties>
2849      //                  ],
2850      //                  '3' => (object) [
2851      //                      <group member properties>
2852      //                  ]
2853      //              ]
2854      //          ]
2855      //      ]
2856      // ]
2857      //
2858      foreach ($results as $key => $result) {
2859          $groupid = $result->gid;
2860          $courseid = $result->courseid;
2861          $coursegroups = $groups[$courseid];
2862          $groupsmembersid = $result->gmid;
2863          $reducefunc = function($carry, $field) use ($result) {
2864              // Iterate over the groups properties and pull
2865              // them out into a separate object.
2866              list($prefix, $field) = explode('.', $field);
2867  
2868              if (property_exists($result, $field)) {
2869                  $carry[$field] = $result->{$field};
2870              }
2871  
2872              return $carry;
2873          };
2874  
2875          if (isset($coursegroups[$groupid])) {
2876              $group = $coursegroups[$groupid];
2877          } else {
2878              $initial = [
2879                  'id' => $groupid,
2880                  'members' => []
2881              ];
2882              $group = (object) array_reduce(
2883                  $groupfields,
2884                  $reducefunc,
2885                  $initial
2886              );
2887          }
2888  
2889          if (!empty($groupsmembersid)) {
2890              $initial = ['id' => $groupsmembersid];
2891              $groupsmembers = (object) array_reduce(
2892                  $groupsmembersfields,
2893                  $reducefunc,
2894                  $initial
2895              );
2896  
2897              $group->members[$groupsmembers->userid] = $groupsmembers;
2898          }
2899  
2900          $coursegroups[$groupid] = $group;
2901          $groups[$courseid] = $coursegroups;
2902      }
2903  
2904      return $groups;
2905  }
2906  
2907  /**
2908   * Gets the capabilities that have been cached in the database for this
2909   * component.
2910   * @deprecated since Moodle 3.6. Please use the Events 2 API.
2911   * @todo final deprecation. To be removed in Moodle 4.0
2912   *
2913   * @access protected To be used from eventslib only
2914   *
2915   * @param string $component examples: 'moodle', 'mod_forum', 'block_quiz_results'
2916   * @return array of events
2917   */
2918  function events_get_cached($component) {
2919      global $DB;
2920  
2921      debugging('Events API using $handlers array has been deprecated in favour of Events 2 API, please use it instead.',
2922              DEBUG_DEVELOPER);
2923  
2924      $cachedhandlers = array();
2925  
2926      if ($storedhandlers = $DB->get_records('events_handlers', array('component'=>$component))) {
2927          foreach ($storedhandlers as $handler) {
2928              $cachedhandlers[$handler->eventname] = array (
2929                  'id'              => $handler->id,
2930                  'handlerfile'     => $handler->handlerfile,
2931                  'handlerfunction' => $handler->handlerfunction,
2932                  'schedule'        => $handler->schedule,
2933                  'internal'        => $handler->internal);
2934          }
2935      }
2936  
2937      return $cachedhandlers;
2938  }
2939  
2940  /**
2941   * Remove all event handlers and queued events
2942   * @deprecated since Moodle 3.6. Please use the Events 2 API.
2943   * @todo final deprecation. To be removed in Moodle 4.0
2944   *
2945   * @category event
2946   * @param string $component examples: 'moodle', 'mod_forum', 'block_quiz_results'
2947   */
2948  function events_uninstall($component) {
2949      debugging('Events API using $handlers array has been deprecated in favour of Events 2 API, please use it instead.',
2950              DEBUG_DEVELOPER);
2951      $cachedhandlers = events_get_cached($component);
2952      events_cleanup($component, $cachedhandlers);
2953  
2954      events_get_handlers('reset');
2955  }
2956  
2957  /**
2958   * Deletes cached events that are no longer needed by the component.
2959   * @deprecated since Moodle 3.6. Please use the Events 2 API.
2960   * @todo final deprecation. To be removed in Moodle 4.0
2961   *
2962   * @access protected To be used from eventslib only
2963   *
2964   * @param string $component examples: 'moodle', 'mod_forum', 'block_quiz_results'
2965   * @param array $cachedhandlers array of the cached events definitions that will be
2966   * @return int number of unused handlers that have been removed
2967   */
2968  function events_cleanup($component, $cachedhandlers) {
2969      global $DB;
2970      debugging('Events API using $handlers array has been deprecated in favour of Events 2 API, please use it instead.',
2971              DEBUG_DEVELOPER);
2972      $deletecount = 0;
2973      foreach ($cachedhandlers as $eventname => $cachedhandler) {
2974          if ($qhandlers = $DB->get_records('events_queue_handlers', array('handlerid'=>$cachedhandler['id']))) {
2975              //debugging("Removing pending events from queue before deleting of event handler: $component - $eventname");
2976              foreach ($qhandlers as $qhandler) {
2977                  events_dequeue($qhandler);
2978              }
2979          }
2980          $DB->delete_records('events_handlers', array('eventname'=>$eventname, 'component'=>$component));
2981          $deletecount++;
2982      }
2983  
2984      return $deletecount;
2985  }
2986  
2987  /**
2988   * Removes this queued handler from the events_queued_handler table
2989   *
2990   * Removes events_queue record from events_queue if no more references to this event object exists
2991   * @deprecated since Moodle 3.6. Please use the Events 2 API.
2992   * @todo final deprecation. To be removed in Moodle 4.0
2993   *
2994   * @access protected To be used from eventslib only
2995   *
2996   * @param stdClass $qhandler A row from the events_queued_handler table
2997   */
2998  function events_dequeue($qhandler) {
2999      global $DB;
3000      debugging('Events API using $handlers array has been deprecated in favour of Events 2 API, please use it instead.',
3001              DEBUG_DEVELOPER);
3002      // first delete the queue handler
3003      $DB->delete_records('events_queue_handlers', array('id'=>$qhandler->id));
3004  
3005      // if no more queued handler is pointing to the same event - delete the event too
3006      if (!$DB->record_exists('events_queue_handlers', array('queuedeventid'=>$qhandler->queuedeventid))) {
3007          $DB->delete_records('events_queue', array('id'=>$qhandler->queuedeventid));
3008      }
3009  }
3010  
3011  /**
3012   * Returns handlers for given event. Uses caching for better perf.
3013   * @deprecated since Moodle 3.6. Please use the Events 2 API.
3014   * @todo final deprecation. To be removed in Moodle 4.0
3015   *
3016   * @access protected To be used from eventslib only
3017   *
3018   * @staticvar array $handlers
3019   * @param string $eventname name of event or 'reset'
3020   * @return array|false array of handlers or false otherwise
3021   */
3022  function events_get_handlers($eventname) {
3023      global $DB;
3024      static $handlers = array();
3025      debugging('Events API using $handlers array has been deprecated in favour of Events 2 API, please use it instead.',
3026              DEBUG_DEVELOPER);
3027  
3028      if ($eventname === 'reset') {
3029          $handlers = array();
3030          return false;
3031      }
3032  
3033      if (!array_key_exists($eventname, $handlers)) {
3034          $handlers[$eventname] = $DB->get_records('events_handlers', array('eventname'=>$eventname));
3035      }
3036  
3037      return $handlers[$eventname];
3038  }
3039  
3040  /**
3041   * This function finds the roles assigned directly to this context only
3042   * i.e. no roles in parent contexts
3043   *
3044   * @deprecated since Moodle 3.6. Please use the get_roles_used_in_context().
3045   * @todo final deprecation. To be removed in Moodle 4.0
3046   * @param context $context
3047   * @return array
3048   */
3049  function get_roles_on_exact_context(context $context) {
3050      debugging('get_roles_on_exact_context() is deprecated, please use get_roles_used_in_context() instead.',
3051          DEBUG_DEVELOPER);
3052  
3053      return get_roles_used_in_context($context, false);
3054  }
3055  
3056  /**
3057   * Find out which roles has assignment on this context
3058   *
3059   * @deprecated since Moodle 3.6. Please use the get_roles_used_in_context().
3060   * @todo final deprecation. To be removed in Moodle 4.0
3061   * @param context $context
3062   * @return array
3063   */
3064  function get_roles_with_assignment_on_context(context $context) {
3065      debugging('get_roles_with_assignment_on_context() is deprecated, please use get_roles_used_in_context() instead.',
3066          DEBUG_DEVELOPER);
3067  
3068      return get_roles_used_in_context($context, false);
3069  }
3070  
3071  /**
3072   * Add the selected user as a contact for the current user
3073   *
3074   * @deprecated since Moodle 3.6
3075   * @param int $contactid the ID of the user to add as a contact
3076   * @param int $blocked 1 if you wish to block the contact
3077   * @param int $userid the user ID of the user we want to add the contact for, defaults to current user if not specified.
3078   * @return bool/int false if the $contactid isnt a valid user id. True if no changes made.
3079   *                  Otherwise returns the result of update_record() or insert_record()
3080   */
3081  function message_add_contact($contactid, $blocked = 0, $userid = 0) {
3082      debugging('message_add_contact() is deprecated. Please use \core_message\api::create_contact_request() instead. ' .
3083          'If you wish to block or unblock a user please use \core_message\api::is_blocked() and ' .
3084          '\core_message\api::block_user() or \core_message\api::unblock_user() respectively.', DEBUG_DEVELOPER);
3085  
3086      global $USER, $DB;
3087  
3088      if (!$DB->record_exists('user', array('id' => $contactid))) {
3089          return false;
3090      }
3091  
3092      if (empty($userid)) {
3093          $userid = $USER->id;
3094      }
3095  
3096      // Check if a record already exists as we may be changing blocking status.
3097      if (\core_message\api::is_contact($userid, $contactid)) {
3098          $isblocked = \core_message\api::is_blocked($userid, $contactid);
3099          // Check if blocking status has been changed.
3100          if ($isblocked != $blocked) {
3101              if ($blocked == 1) {
3102                  if (!$isblocked) {
3103                      \core_message\api::block_user($userid, $contactid);
3104                  }
3105              } else {
3106                  \core_message\api::unblock_user($userid, $contactid);
3107              }
3108  
3109              return true;
3110          } else {
3111              // No change to blocking status.
3112              return true;
3113          }
3114      } else {
3115          if ($blocked == 1) {
3116              if (!\core_message\api::is_blocked($userid, $contactid)) {
3117                  \core_message\api::block_user($userid, $contactid);
3118              }
3119          } else {
3120              \core_message\api::unblock_user($userid, $contactid);
3121              if (!\core_message\api::does_contact_request_exist($userid, $contactid)) {
3122                  \core_message\api::create_contact_request($userid, $contactid);
3123              }
3124          }
3125  
3126          return true;
3127      }
3128  }
3129  
3130  /**
3131   * Remove a contact.
3132   *
3133   * @deprecated since Moodle 3.6
3134   * @param int $contactid the user ID of the contact to remove
3135   * @param int $userid the user ID of the user we want to remove the contacts for, defaults to current user if not specified.
3136   * @return bool returns the result of delete_records()
3137   */
3138  function message_remove_contact($contactid, $userid = 0) {
3139      debugging('message_remove_contact() is deprecated. Please use \core_message\api::remove_contact() instead.',
3140          DEBUG_DEVELOPER);
3141  
3142      global $USER;
3143  
3144      if (empty($userid)) {
3145          $userid = $USER->id;
3146      }
3147  
3148      \core_message\api::remove_contact($userid, $contactid);
3149  
3150      return true;
3151  }
3152  
3153  /**
3154   * Unblock a contact.
3155   *
3156   * @deprecated since Moodle 3.6
3157   * @param int $contactid the user ID of the contact to unblock
3158   * @param int $userid the user ID of the user we want to unblock the contact for, defaults to current user
3159   *  if not specified.
3160   * @return bool returns the result of delete_records()
3161   */
3162  function message_unblock_contact($contactid, $userid = 0) {
3163      debugging('message_unblock_contact() is deprecated. Please use \core_message\api::unblock_user() instead.',
3164          DEBUG_DEVELOPER);
3165  
3166      global $DB, $USER;
3167  
3168      if (!$DB->record_exists('user', array('id' => $contactid))) {
3169          return false;
3170      }
3171  
3172      if (empty($userid)) {
3173          $userid = $USER->id;
3174      }
3175  
3176      \core_message\api::unblock_user($userid, $contactid);
3177  
3178      return true;
3179  }
3180  
3181  /**
3182   * Block a user.
3183   *
3184   * @deprecated since Moodle 3.6
3185   * @param int $contactid the user ID of the user to block
3186   * @param int $userid the user ID of the user we want to unblock the contact for, defaults to current user
3187   *  if not specified.
3188   * @return bool
3189   */
3190  function message_block_contact($contactid, $userid = 0) {
3191      debugging('message_block_contact() is deprecated. Please use \core_message\api::is_blocked() and ' .
3192          '\core_message\api::block_user() instead.', DEBUG_DEVELOPER);
3193  
3194      global $DB, $USER;
3195  
3196      if (!$DB->record_exists('user', array('id' => $contactid))) {
3197          return false;
3198      }
3199  
3200      if (empty($userid)) {
3201          $userid = $USER->id;
3202      }
3203  
3204      if (!\core_message\api::is_blocked($userid, $contactid)) {
3205          \core_message\api::block_user($userid, $contactid);
3206      }
3207  
3208      return true;
3209  }
3210  
3211  /**
3212   * Load a user's contact record
3213   *
3214   * @deprecated since Moodle 3.6
3215   * @param int $contactid the user ID of the user whose contact record you want
3216   * @return array message contacts
3217   */
3218  function message_get_contact($contactid) {
3219      debugging('message_get_contact() is deprecated. Please use \core_message\api::get_contact() instead.',
3220          DEBUG_DEVELOPER);
3221  
3222      global $USER;
3223  
3224      return \core_message\api::get_contact($USER->id, $contactid);
3225  }
3226  
3227  /**
3228   * Returns list of courses, for whole site, or category
3229   *
3230   * Similar to get_courses, but allows paging
3231   * Important: Using c.* for fields is extremely expensive because
3232   *            we are using distinct. You almost _NEVER_ need all the fields
3233   *            in such a large SELECT
3234   *
3235   * @deprecated since Moodle 3.7
3236   * @todo The final deprecation of this function will take place in Moodle 41 - see MDL-65319.
3237   *
3238   * @param string|int $categoryid Either a category id or 'all' for everything
3239   * @param string $sort A field and direction to sort by
3240   * @param string $fields The additional fields to return
3241   * @param int $totalcount Reference for the number of courses
3242   * @param string $limitfrom The course to start from
3243   * @param string $limitnum The number of courses to limit to
3244   * @return array Array of courses
3245   */
3246  function get_courses_page($categoryid="all", $sort="c.sortorder ASC", $fields="c.*",
3247                            &$totalcount, $limitfrom="", $limitnum="") {
3248      debugging('Function get_courses_page() is deprecated. Please use core_course_category::get_courses() ' .
3249          'or core_course_category::search_courses()', DEBUG_DEVELOPER);
3250      global $USER, $CFG, $DB;
3251  
3252      $params = array();
3253  
3254      $categoryselect = "";
3255      if ($categoryid !== "all" && is_numeric($categoryid)) {
3256          $categoryselect = "WHERE c.category = :catid";
3257          $params['catid'] = $categoryid;
3258      } else {
3259          $categoryselect = "";
3260      }
3261  
3262      $ccselect = ', ' . context_helper::get_preload_record_columns_sql('ctx');
3263      $ccjoin = "LEFT JOIN {context} ctx ON (ctx.instanceid = c.id AND ctx.contextlevel = :contextlevel)";
3264      $params['contextlevel'] = CONTEXT_COURSE;
3265  
3266      $totalcount = 0;
3267      if (!$limitfrom) {
3268          $limitfrom = 0;
3269      }
3270      $visiblecourses = array();
3271  
3272      $sql = "SELECT $fields $ccselect
3273                FROM {course} c
3274                $ccjoin
3275             $categoryselect
3276            ORDER BY $sort";
3277  
3278      // Pull out all course matching the cat.
3279      $rs = $DB->get_recordset_sql($sql, $params);
3280      // Iteration will have to be done inside loop to keep track of the limitfrom and limitnum.
3281      foreach ($rs as $course) {
3282          context_helper::preload_from_record($course);
3283          if (core_course_category::can_view_course_info($course)) {
3284              $totalcount++;
3285              if ($totalcount > $limitfrom && (!$limitnum or count($visiblecourses) < $limitnum)) {
3286                  $visiblecourses [$course->id] = $course;
3287              }
3288          }
3289      }
3290      $rs->close();
3291      return $visiblecourses;
3292  }
3293  
3294  /**
3295   * Returns the models that generated insights in the provided context.
3296   *
3297   * @deprecated since Moodle 3.8 MDL-66091 - please do not use this function any more.
3298   * @todo MDL-65799 This will be deleted in Moodle 4.2
3299   * @see \core_analytics\manager::cached_models_with_insights
3300   * @param  \context $context
3301   * @return int[]
3302   */
3303  function report_insights_context_insights(\context $context) {
3304  
3305      debugging('report_insights_context_insights is deprecated. Please use ' .
3306          '\core_analytics\manager::cached_models_with_insights instead', DEBUG_DEVELOPER);
3307  
3308      return \core_analytics\manager::cached_models_with_insights($context);
3309  }
3310  
3311  /**
3312   * Retrieve all metadata for the requested modules
3313   *
3314   * @deprecated since 3.9.
3315   * @param object $course The Course
3316   * @param array $modnames An array containing the list of modules and their
3317   * names
3318   * @param int $sectionreturn The section to return to
3319   * @return array A list of stdClass objects containing metadata about each
3320   * module
3321   */
3322  function get_module_metadata($course, $modnames, $sectionreturn = null) {
3323      global $OUTPUT;
3324  
3325      debugging('get_module_metadata is deprecated. Please use \core_course\local\service\content_item_service instead.');
3326  
3327      // get_module_metadata will be called once per section on the page and courses may show
3328      // different modules to one another
3329      static $modlist = array();
3330      if (!isset($modlist[$course->id])) {
3331          $modlist[$course->id] = array();
3332      }
3333  
3334      $return = array();
3335      $urlbase = new moodle_url('/course/mod.php', array('id' => $course->id, 'sesskey' => sesskey()));
3336      if ($sectionreturn !== null) {
3337          $urlbase->param('sr', $sectionreturn);
3338      }
3339      foreach($modnames as $modname => $modnamestr) {
3340          if (!course_allowed_module($course, $modname)) {
3341              continue;
3342          }
3343          if (isset($modlist[$course->id][$modname])) {
3344              // This module is already cached
3345              $return += $modlist[$course->id][$modname];
3346              continue;
3347          }
3348          $modlist[$course->id][$modname] = array();
3349  
3350          // Create an object for a default representation of this module type in the activity chooser. It will be used
3351          // if module does not implement callback get_shortcuts() and it will also be passed to the callback if it exists.
3352          $defaultmodule = new stdClass();
3353          $defaultmodule->title = $modnamestr;
3354          $defaultmodule->name = $modname;
3355          $defaultmodule->link = new moodle_url($urlbase, array('add' => $modname));
3356          $defaultmodule->icon = $OUTPUT->pix_icon('icon', '', $defaultmodule->name, array('class' => 'icon'));
3357          $sm = get_string_manager();
3358          if ($sm->string_exists('modulename_help', $modname)) {
3359              $defaultmodule->help = get_string('modulename_help', $modname);
3360              if ($sm->string_exists('modulename_link', $modname)) {  // Link to further info in Moodle docs.
3361                  $link = get_string('modulename_link', $modname);
3362                  $linktext = get_string('morehelp');
3363                  $defaultmodule->help .= html_writer::tag('div',
3364                      $OUTPUT->doc_link($link, $linktext, true), array('class' => 'helpdoclink'));
3365              }
3366          }
3367          $defaultmodule->archetype = plugin_supports('mod', $modname, FEATURE_MOD_ARCHETYPE, MOD_ARCHETYPE_OTHER);
3368  
3369          // Each module can implement callback modulename_get_shortcuts() in its lib.php and return the list
3370          // of elements to be added to activity chooser.
3371          $items = component_callback($modname, 'get_shortcuts', array($defaultmodule), null);
3372          if ($items !== null) {
3373              foreach ($items as $item) {
3374                  // Add all items to the return array. All items must have different links, use them as a key in the return array.
3375                  if (!isset($item->archetype)) {
3376                      $item->archetype = $defaultmodule->archetype;
3377                  }
3378                  if (!isset($item->icon)) {
3379                      $item->icon = $defaultmodule->icon;
3380                  }
3381                  // If plugin returned the only one item with the same link as default item - cache it as $modname,
3382                  // otherwise append the link url to the module name.
3383                  $item->name = (count($items) == 1 &&
3384                      $item->link->out() === $defaultmodule->link->out()) ? $modname : $modname . ':' . $item->link;
3385  
3386                  // If the module provides the helptext property, append it to the help text to match the look and feel
3387                  // of the default course modules.
3388                  if (isset($item->help) && isset($item->helplink)) {
3389                      $linktext = get_string('morehelp');
3390                      $item->help .= html_writer::tag('div',
3391                          $OUTPUT->doc_link($item->helplink, $linktext, true), array('class' => 'helpdoclink'));
3392                  }
3393                  $modlist[$course->id][$modname][$item->name] = $item;
3394              }
3395              $return += $modlist[$course->id][$modname];
3396              // If get_shortcuts() callback is defined, the default module action is not added.
3397              // It is a responsibility of the callback to add it to the return value unless it is not needed.
3398              continue;
3399          }
3400  
3401          // The callback get_shortcuts() was not found, use the default item for the activity chooser.
3402          $modlist[$course->id][$modname][$modname] = $defaultmodule;
3403          $return[$modname] = $defaultmodule;
3404      }
3405  
3406      core_collator::asort_objects_by_property($return, 'title');
3407      return $return;
3408  }
3409  
3410  /**
3411   * Runs a single cron task. This function assumes it is displaying output in pseudo-CLI mode.
3412   *
3413   * The function will fail if the task is disabled.
3414   *
3415   * Warning: Because this function closes the browser session, it may not be safe to continue
3416   * with other processing (other than displaying the rest of the page) after using this function!
3417   *
3418   * @deprecated since Moodle 3.9 MDL-63580. Please use the \core\task\manager::run_from_cli($task).
3419   * @todo final deprecation. To be removed in Moodle 4.3 MDL-63594.
3420   * @param \core\task\scheduled_task $task Task to run
3421   * @return bool True if cron run successful
3422   */
3423  function cron_run_single_task(\core\task\scheduled_task $task) {
3424      debugging('cron_run_single_task() is deprecated. Please use \\core\task\manager::run_from_cli() instead.',
3425          DEBUG_DEVELOPER);
3426      return \core\task\manager::run_from_cli($task);
3427  }
3428  
3429  /**
3430   * Executes cron functions for a specific type of plugin.
3431   *
3432   * @param string $plugintype Plugin type (e.g. 'report')
3433   * @param string $description If specified, will display 'Starting (whatever)'
3434   *   and 'Finished (whatever)' lines, otherwise does not display
3435   *
3436   * @deprecated since Moodle 3.9 MDL-52846. Please use new task API.
3437   * @todo MDL-61165 This will be deleted in Moodle 4.3.
3438   */
3439  function cron_execute_plugin_type($plugintype, $description = null) {
3440      global $DB;
3441  
3442      // Get list from plugin => function for all plugins.
3443      $plugins = get_plugin_list_with_function($plugintype, 'cron');
3444  
3445      // Modify list for backward compatibility (different files/names).
3446      $plugins = cron_bc_hack_plugin_functions($plugintype, $plugins);
3447  
3448      // Return if no plugins with cron function to process.
3449      if (!$plugins) {
3450          return;
3451      }
3452  
3453      if ($description) {
3454          mtrace('Starting '.$description);
3455      }
3456  
3457      foreach ($plugins as $component => $cronfunction) {
3458          $dir = core_component::get_component_directory($component);
3459  
3460          // Get cron period if specified in version.php, otherwise assume every cron.
3461          $cronperiod = 0;
3462          if (file_exists("$dir/version.php")) {
3463              $plugin = new stdClass();
3464              include("$dir/version.php");
3465              if (isset($plugin->cron)) {
3466                  $cronperiod = $plugin->cron;
3467              }
3468          }
3469  
3470          // Using last cron and cron period, don't run if it already ran recently.
3471          $lastcron = get_config($component, 'lastcron');
3472          if ($cronperiod && $lastcron) {
3473              if ($lastcron + $cronperiod > time()) {
3474                  // Do not execute cron yet.
3475                  continue;
3476              }
3477          }
3478  
3479          mtrace('Processing cron function for ' . $component . '...');
3480          debugging("Use of legacy cron is deprecated ($cronfunction). Please use scheduled tasks.", DEBUG_DEVELOPER);
3481          cron_trace_time_and_memory();
3482          $pre_dbqueries = $DB->perf_get_queries();
3483          $pre_time = microtime(true);
3484  
3485          $cronfunction();
3486  
3487          mtrace("done. (" . ($DB->perf_get_queries() - $pre_dbqueries) . " dbqueries, " .
3488                  round(microtime(true) - $pre_time, 2) . " seconds)");
3489  
3490          set_config('lastcron', time(), $component);
3491          core_php_time_limit::raise();
3492      }
3493  
3494      if ($description) {
3495          mtrace('Finished ' . $description);
3496      }
3497  }
3498  
3499  /**
3500   * Used to add in old-style cron functions within plugins that have not been converted to the
3501   * new standard API. (The standard API is frankenstyle_name_cron() in lib.php; some types used
3502   * cron.php and some used a different name.)
3503   *
3504   * @param string $plugintype Plugin type e.g. 'report'
3505   * @param array $plugins Array from plugin name (e.g. 'report_frog') to function name (e.g.
3506   *   'report_frog_cron') for plugin cron functions that were already found using the new API
3507   * @return array Revised version of $plugins that adds in any extra plugin functions found by
3508   *   looking in the older location
3509   *
3510   * @deprecated since Moodle 3.9 MDL-52846. Please use new task API.
3511   * @todo MDL-61165 This will be deleted in Moodle 4.3.
3512   */
3513  function cron_bc_hack_plugin_functions($plugintype, $plugins) {
3514      global $CFG; // Mandatory in case it is referenced by include()d PHP script.
3515  
3516      if ($plugintype === 'report') {
3517          // Admin reports only - not course report because course report was
3518          // never implemented before, so doesn't need BC.
3519          foreach (core_component::get_plugin_list($plugintype) as $pluginname => $dir) {
3520              $component = $plugintype . '_' . $pluginname;
3521              if (isset($plugins[$component])) {
3522                  // We already have detected the function using the new API.
3523                  continue;
3524              }
3525              if (!file_exists("$dir/cron.php")) {
3526                  // No old style cron file present.
3527                  continue;
3528              }
3529              include_once("$dir/cron.php");
3530              $cronfunction = $component . '_cron';
3531              if (function_exists($cronfunction)) {
3532                  $plugins[$component] = $cronfunction;
3533              } else {
3534                  debugging("Invalid legacy cron.php detected in $component, " .
3535                          "please use lib.php instead");
3536              }
3537          }
3538      } else if (strpos($plugintype, 'grade') === 0) {
3539          // Detect old style cron function names.
3540          // Plugin gradeexport_frog used to use grade_export_frog_cron() instead of
3541          // new standard API gradeexport_frog_cron(). Also applies to gradeimport, gradereport.
3542          foreach (core_component::get_plugin_list($plugintype) as $pluginname => $dir) {
3543              $component = $plugintype.'_'.$pluginname;
3544              if (isset($plugins[$component])) {
3545                  // We already have detected the function using the new API.
3546                  continue;
3547              }
3548              if (!file_exists("$dir/lib.php")) {
3549                  continue;
3550              }
3551              include_once("$dir/lib.php");
3552              $cronfunction = str_replace('grade', 'grade_', $plugintype) . '_' .
3553                      $pluginname . '_cron';
3554              if (function_exists($cronfunction)) {
3555                  $plugins[$component] = $cronfunction;
3556              }
3557          }
3558      }
3559  
3560      return $plugins;
3561  }
3562  
3563  /**
3564   * Returns the SQL used by the participants table.
3565   *
3566   * @deprecated since Moodle 3.9 MDL-68612 - See \core_user\table\participants_search for an improved way to fetch participants.
3567   * @param int $courseid The course id
3568   * @param int $groupid The groupid, 0 means all groups and USERSWITHOUTGROUP no group
3569   * @param int $accesssince The time since last access, 0 means any time
3570   * @param int $roleid The role id, 0 means all roles and -1 no roles
3571   * @param int $enrolid The enrolment id, 0 means all enrolment methods will be returned.
3572   * @param int $statusid The user enrolment status, -1 means all enrolments regardless of the status will be returned, if allowed.
3573   * @param string|array $search The search that was performed, empty means perform no search
3574   * @param string $additionalwhere Any additional SQL to add to where
3575   * @param array $additionalparams The additional params
3576   * @return array
3577   */
3578  function user_get_participants_sql($courseid, $groupid = 0, $accesssince = 0, $roleid = 0, $enrolid = 0, $statusid = -1,
3579                                     $search = '', $additionalwhere = '', $additionalparams = array()) {
3580      global $DB, $USER, $CFG;
3581  
3582      $deprecatedtext = __FUNCTION__ . '() is deprecated. ' .
3583                   'Please use \core\table\participants_search::class with table filtersets instead.';
3584      debugging($deprecatedtext, DEBUG_DEVELOPER);
3585  
3586      // Get the context.
3587      $context = \context_course::instance($courseid, MUST_EXIST);
3588  
3589      $isfrontpage = ($courseid == SITEID);
3590  
3591      // Default filter settings. We only show active by default, especially if the user has no capability to review enrolments.
3592      $onlyactive = true;
3593      $onlysuspended = false;
3594      if (has_capability('moodle/course:enrolreview', $context) && (has_capability('moodle/course:viewsuspendedusers', $context))) {
3595          switch ($statusid) {
3596              case ENROL_USER_ACTIVE:
3597                  // Nothing to do here.
3598                  break;
3599              case ENROL_USER_SUSPENDED:
3600                  $onlyactive = false;
3601                  $onlysuspended = true;
3602                  break;
3603              default:
3604                  // If the user has capability to review user enrolments, but statusid is set to -1, set $onlyactive to false.
3605                  $onlyactive = false;
3606                  break;
3607          }
3608      }
3609  
3610      list($esql, $params) = get_enrolled_sql($context, null, $groupid, $onlyactive, $onlysuspended, $enrolid);
3611  
3612      $joins = array('FROM {user} u');
3613      $wheres = array();
3614  
3615      $userfields = get_extra_user_fields($context);
3616      $userfieldssql = user_picture::fields('u', $userfields);
3617  
3618      if ($isfrontpage) {
3619          $select = "SELECT $userfieldssql, u.lastaccess";
3620          $joins[] = "JOIN ($esql) e ON e.id = u.id"; // Everybody on the frontpage usually.
3621          if ($accesssince) {
3622              $wheres[] = user_get_user_lastaccess_sql($accesssince);
3623          }
3624      } else {
3625          $select = "SELECT $userfieldssql, COALESCE(ul.timeaccess, 0) AS lastaccess";
3626          $joins[] = "JOIN ($esql) e ON e.id = u.id"; // Course enrolled users only.
3627          // Not everybody has accessed the course yet.
3628          $joins[] = 'LEFT JOIN {user_lastaccess} ul ON (ul.userid = u.id AND ul.courseid = :courseid)';
3629          $params['courseid'] = $courseid;
3630          if ($accesssince) {
3631              $wheres[] = user_get_course_lastaccess_sql($accesssince);
3632          }
3633      }
3634  
3635      // Performance hacks - we preload user contexts together with accounts.
3636      $ccselect = ', ' . context_helper::get_preload_record_columns_sql('ctx');
3637      $ccjoin = 'LEFT JOIN {context} ctx ON (ctx.instanceid = u.id AND ctx.contextlevel = :contextlevel)';
3638      $params['contextlevel'] = CONTEXT_USER;
3639      $select .= $ccselect;
3640      $joins[] = $ccjoin;
3641  
3642      // Limit list to users with some role only.
3643      if ($roleid) {
3644          // We want to query both the current context and parent contexts.
3645          list($relatedctxsql, $relatedctxparams) = $DB->get_in_or_equal($context->get_parent_context_ids(true),
3646              SQL_PARAMS_NAMED, 'relatedctx');
3647  
3648          // Get users without any role.
3649          if ($roleid == -1) {
3650              $wheres[] = "u.id NOT IN (SELECT userid FROM {role_assignments} WHERE contextid $relatedctxsql)";
3651              $params = array_merge($params, $relatedctxparams);
3652          } else {
3653              $wheres[] = "u.id IN (SELECT userid FROM {role_assignments} WHERE roleid = :roleid AND contextid $relatedctxsql)";
3654              $params = array_merge($params, array('roleid' => $roleid), $relatedctxparams);
3655          }
3656      }
3657  
3658      if (!empty($search)) {
3659          if (!is_array($search)) {
3660              $search = [$search];
3661          }
3662          foreach ($search as $index => $keyword) {
3663              $searchkey1 = 'search' . $index . '1';
3664              $searchkey2 = 'search' . $index . '2';
3665              $searchkey3 = 'search' . $index . '3';
3666              $searchkey4 = 'search' . $index . '4';
3667              $searchkey5 = 'search' . $index . '5';
3668              $searchkey6 = 'search' . $index . '6';
3669              $searchkey7 = 'search' . $index . '7';
3670  
3671              $conditions = array();
3672              // Search by fullname.
3673              $fullname = $DB->sql_fullname('u.firstname', 'u.lastname');
3674              $conditions[] = $DB->sql_like($fullname, ':' . $searchkey1, false, false);
3675  
3676              // Search by email.
3677              $email = $DB->sql_like('email', ':' . $searchkey2, false, false);
3678              if (!in_array('email', $userfields)) {
3679                  $maildisplay = 'maildisplay' . $index;
3680                  $userid1 = 'userid' . $index . '1';
3681                  // Prevent users who hide their email address from being found by others
3682                  // who aren't allowed to see hidden email addresses.
3683                  $email = "(". $email ." AND (" .
3684                          "u.maildisplay <> :$maildisplay " .
3685                          "OR u.id = :$userid1". // User can always find himself.
3686                          "))";
3687                  $params[$maildisplay] = core_user::MAILDISPLAY_HIDE;
3688                  $params[$userid1] = $USER->id;
3689              }
3690              $conditions[] = $email;
3691  
3692              // Search by idnumber.
3693              $idnumber = $DB->sql_like('idnumber', ':' . $searchkey3, false, false);
3694              if (!in_array('idnumber', $userfields)) {
3695                  $userid2 = 'userid' . $index . '2';
3696                  // Users who aren't allowed to see idnumbers should at most find themselves
3697                  // when searching for an idnumber.
3698                  $idnumber = "(". $idnumber . " AND u.id = :$userid2)";
3699                  $params[$userid2] = $USER->id;
3700              }
3701              $conditions[] = $idnumber;
3702  
3703              if (!empty($CFG->showuseridentity)) {
3704                  // Search all user identify fields.
3705                  $extrasearchfields = explode(',', $CFG->showuseridentity);
3706                  foreach ($extrasearchfields as $extrasearchfield) {
3707                      if (in_array($extrasearchfield, ['email', 'idnumber', 'country'])) {
3708                          // Already covered above. Search by country not supported.
3709                          continue;
3710                      }
3711                      $param = $searchkey3 . $extrasearchfield;
3712                      $condition = $DB->sql_like($extrasearchfield, ':' . $param, false, false);
3713                      $params[$param] = "%$keyword%";
3714                      if (!in_array($extrasearchfield, $userfields)) {
3715                          // User cannot see this field, but allow match if their own account.
3716                          $userid3 = 'userid' . $index . '3' . $extrasearchfield;
3717                          $condition = "(". $condition . " AND u.id = :$userid3)";
3718                          $params[$userid3] = $USER->id;
3719                      }
3720                      $conditions[] = $condition;
3721                  }
3722              }
3723  
3724              // Search by middlename.
3725              $middlename = $DB->sql_like('middlename', ':' . $searchkey4, false, false);
3726              $conditions[] = $middlename;
3727  
3728              // Search by alternatename.
3729              $alternatename = $DB->sql_like('alternatename', ':' . $searchkey5, false, false);
3730              $conditions[] = $alternatename;
3731  
3732              // Search by firstnamephonetic.
3733              $firstnamephonetic = $DB->sql_like('firstnamephonetic', ':' . $searchkey6, false, false);
3734              $conditions[] = $firstnamephonetic;
3735  
3736              // Search by lastnamephonetic.
3737              $lastnamephonetic = $DB->sql_like('lastnamephonetic', ':' . $searchkey7, false, false);
3738              $conditions[] = $lastnamephonetic;
3739  
3740              $wheres[] = "(". implode(" OR ", $conditions) .") ";
3741              $params[$searchkey1] = "%$keyword%";
3742              $params[$searchkey2] = "%$keyword%";
3743              $params[$searchkey3] = "%$keyword%";
3744              $params[$searchkey4] = "%$keyword%";
3745              $params[$searchkey5] = "%$keyword%";
3746              $params[$searchkey6] = "%$keyword%";
3747              $params[$searchkey7] = "%$keyword%";
3748          }
3749      }
3750  
3751      if (!empty($additionalwhere)) {
3752          $wheres[] = $additionalwhere;
3753          $params = array_merge($params, $additionalparams);
3754      }
3755  
3756      $from = implode("\n", $joins);
3757      if ($wheres) {
3758          $where = 'WHERE ' . implode(' AND ', $wheres);
3759      } else {
3760          $where = '';
3761      }
3762  
3763      return array($select, $from, $where, $params);
3764  }
3765  
3766  /**
3767   * Returns the total number of participants for a given course.
3768   *
3769   * @deprecated since Moodle 3.9 MDL-68612 - See \core_user\table\participants_search for an improved way to fetch participants.
3770   * @param int $courseid The course id
3771   * @param int $groupid The groupid, 0 means all groups and USERSWITHOUTGROUP no group
3772   * @param int $accesssince The time since last access, 0 means any time
3773   * @param int $roleid The role id, 0 means all roles
3774   * @param int $enrolid The applied filter for the user enrolment ID.
3775   * @param int $status The applied filter for the user's enrolment status.
3776   * @param string|array $search The search that was performed, empty means perform no search
3777   * @param string $additionalwhere Any additional SQL to add to where
3778   * @param array $additionalparams The additional params
3779   * @return int
3780   */
3781  function user_get_total_participants($courseid, $groupid = 0, $accesssince = 0, $roleid = 0, $enrolid = 0, $statusid = -1,
3782                                       $search = '', $additionalwhere = '', $additionalparams = array()) {
3783      global $DB;
3784  
3785      $deprecatedtext = __FUNCTION__ . '() is deprecated. ' .
3786                        'Please use \core\table\participants_search::class with table filtersets instead.';
3787      debugging($deprecatedtext, DEBUG_DEVELOPER);
3788  
3789      list($select, $from, $where, $params) = user_get_participants_sql($courseid, $groupid, $accesssince, $roleid, $enrolid,
3790          $statusid, $search, $additionalwhere, $additionalparams);
3791  
3792      return $DB->count_records_sql("SELECT COUNT(u.id) $from $where", $params);
3793  }
3794  
3795  /**
3796   * Returns the participants for a given course.
3797   *
3798   * @deprecated since Moodle 3.9 MDL-68612 - See \core_user\table\participants_search for an improved way to fetch participants.
3799   * @param int $courseid The course id
3800   * @param int $groupid The groupid, 0 means all groups and USERSWITHOUTGROUP no group
3801   * @param int $accesssince The time since last access
3802   * @param int $roleid The role id
3803   * @param int $enrolid The applied filter for the user enrolment ID.
3804   * @param int $status The applied filter for the user's enrolment status.
3805   * @param string $search The search that was performed
3806   * @param string $additionalwhere Any additional SQL to add to where
3807   * @param array $additionalparams The additional params
3808   * @param string $sort The SQL sort
3809   * @param int $limitfrom return a subset of records, starting at this point (optional).
3810   * @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set).
3811   * @return moodle_recordset
3812   */
3813  function user_get_participants($courseid, $groupid = 0, $accesssince, $roleid, $enrolid = 0, $statusid, $search,
3814                                 $additionalwhere = '', $additionalparams = array(), $sort = '', $limitfrom = 0, $limitnum = 0) {
3815      global $DB;
3816  
3817      $deprecatedtext = __FUNCTION__ . '() is deprecated. ' .
3818                        'Please use \core\table\participants_search::class with table filtersets instead.';
3819      debugging($deprecatedtext, DEBUG_DEVELOPER);
3820  
3821      list($select, $from, $where, $params) = user_get_participants_sql($courseid, $groupid, $accesssince, $roleid, $enrolid,
3822          $statusid, $search, $additionalwhere, $additionalparams);
3823  
3824      return $DB->get_recordset_sql("$select $from $where $sort", $params, $limitfrom, $limitnum);
3825  }