Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.0.x will end 8 May 2023 (12 months).
  • Bug fixes for security issues in 4.0.x will end 13 November 2023 (18 months).
  • PHP version: minimum PHP 7.3.0 Note: the minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is also supported.

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

   1  <?php
   2  // This file is part of Moodle - https://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  /**
  18   * Defines settingpages and externalpages under the "server" category.
  19   *
  20   * @package     core
  21   * @category    admin
  22   * @copyright   2006 Martin Dougiamas
  23   * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   */
  25  
  26  defined('MOODLE_INTERNAL') || die();
  27  
  28  if ($hassiteconfig) {
  29      // System paths.
  30      $temp = new admin_settingpage('systempaths', new lang_string('systempaths', 'admin'));
  31      $temp->add(new admin_setting_configexecutable('pathtophp', new lang_string('pathtophp', 'admin'),
  32          new lang_string('configpathtophp', 'admin'), ''));
  33      $temp->add(new admin_setting_configexecutable('pathtodu', new lang_string('pathtodu', 'admin'),
  34          new lang_string('configpathtodu', 'admin'), ''));
  35      $temp->add(new admin_setting_configexecutable('aspellpath', new lang_string('aspellpath', 'admin'),
  36          new lang_string('edhelpaspellpath'), ''));
  37      $temp->add(new admin_setting_configexecutable('pathtodot', new lang_string('pathtodot', 'admin'),
  38          new lang_string('pathtodot_help', 'admin'), ''));
  39      $temp->add(new admin_setting_configexecutable('pathtogs', new lang_string('pathtogs', 'admin'),
  40          new lang_string('pathtogs_help', 'admin'), '/usr/bin/gs'));
  41      $temp->add(new admin_setting_configexecutable('pathtopdftoppm', new lang_string('pathtopdftoppm', 'admin'),
  42          new lang_string('pathtopdftoppm_help', 'admin'), ''));
  43      $temp->add(new admin_setting_configexecutable('pathtopython', new lang_string('pathtopython', 'admin'),
  44          new lang_string('pathtopythondesc', 'admin'), ''));
  45      $ADMIN->add('server', $temp);
  46  
  47      // Support contact.
  48      $temp = new admin_settingpage('supportcontact', new lang_string('supportcontact', 'admin'));
  49      $primaryadmin = get_admin();
  50      if ($primaryadmin) {
  51          $primaryadminname = fullname($primaryadmin, true);
  52      } else {
  53          // No defaults during installation - admin user must be created first.
  54          $primaryadminname = null;
  55      }
  56      $temp->add(new admin_setting_configtext('supportname', new lang_string('supportname', 'admin'),
  57          new lang_string('configsupportname', 'admin'), $primaryadminname, PARAM_NOTAGS));
  58      $setting = new admin_setting_requiredtext('supportemail', new lang_string('supportemail', 'admin'),
  59          new lang_string('configsupportemail', 'admin'), null, PARAM_EMAIL);
  60      $setting->set_force_ltr(true);
  61      $temp->add($setting);
  62      $temp->add(new admin_setting_configtext('supportpage', new lang_string('supportpage', 'admin'),
  63          new lang_string('configsupportpage', 'admin'), '', PARAM_URL));
  64      $ADMIN->add('server', $temp);
  65  
  66      // Session handling.
  67      $temp = new admin_settingpage('sessionhandling', new lang_string('sessionhandling', 'admin'));
  68      if (empty($CFG->session_handler_class) and $DB->session_lock_supported()) {
  69          $temp->add(new admin_setting_configcheckbox('dbsessions', new lang_string('dbsessions', 'admin'),
  70              new lang_string('configdbsessions', 'admin'), 0));
  71      }
  72  
  73      $temp->add(new admin_setting_configduration('sessiontimeout', new lang_string('sessiontimeout', 'admin'),
  74          new lang_string('configsessiontimeout', 'admin'), 8 * 60 * 60));
  75  
  76      $sessiontimeoutwarning = new admin_setting_configduration('sessiontimeoutwarning',
  77          new lang_string('sessiontimeoutwarning', 'admin'),
  78          new lang_string('configsessiontimeoutwarning', 'admin'), 20 * 60);
  79  
  80      $sessiontimeoutwarning->set_validate_function(function(int $value): string {
  81          global $CFG;
  82          // Check sessiontimeoutwarning is less than sessiontimeout.
  83          if ($CFG->sessiontimeout <= $value) {
  84              return get_string('configsessiontimeoutwarningcheck', 'admin');
  85          } else {
  86              return '';
  87          }
  88      });
  89  
  90      $temp->add($sessiontimeoutwarning);
  91  
  92      $temp->add(new admin_setting_configtext('sessioncookie', new lang_string('sessioncookie', 'admin'),
  93          new lang_string('configsessioncookie', 'admin'), '', PARAM_ALPHANUM));
  94      $temp->add(new admin_setting_configtext('sessioncookiepath', new lang_string('sessioncookiepath', 'admin'),
  95          new lang_string('configsessioncookiepath', 'admin'), '', PARAM_RAW));
  96      $temp->add(new admin_setting_configtext('sessioncookiedomain', new lang_string('sessioncookiedomain', 'admin'),
  97          new lang_string('configsessioncookiedomain', 'admin'), '', PARAM_RAW, 50));
  98      $ADMIN->add('server', $temp);
  99  
 100      // Statistics.
 101      $temp = new admin_settingpage('stats', new lang_string('stats'), 'moodle/site:config', empty($CFG->enablestats));
 102      $temp->add(new admin_setting_configselect('statsfirstrun', new lang_string('statsfirstrun', 'admin'),
 103          new lang_string('configstatsfirstrun', 'admin'), 'none',
 104          [
 105              'none' => new lang_string('none'),
 106              60 * 60 * 24 * 7 => new lang_string('numweeks', 'moodle', 1),
 107              60 * 60 * 24 * 14 => new lang_string('numweeks', 'moodle', 2),
 108              60 * 60 * 24 * 21 => new lang_string('numweeks', 'moodle', 3),
 109              60 * 60 * 24 * 28 => new lang_string('nummonths', 'moodle', 1),
 110              60 * 60 * 24 * 56 => new lang_string('nummonths', 'moodle', 2),
 111              60 * 60 * 24 * 84 => new lang_string('nummonths', 'moodle', 3),
 112              60 * 60 * 24 * 112 => new lang_string('nummonths', 'moodle', 4),
 113              60 * 60 * 24 * 140 => new lang_string('nummonths', 'moodle', 5),
 114              60 * 60 * 24 * 168 => new lang_string('nummonths', 'moodle', 6),
 115              'all' => new lang_string('all')
 116          ]
 117      ));
 118      $temp->add(new admin_setting_configselect('statsmaxruntime', new lang_string('statsmaxruntime', 'admin'),
 119          new lang_string('configstatsmaxruntime3', 'admin'), 0,
 120          [
 121              0 => new lang_string('untilcomplete'),
 122              60 * 30 => '10 ' . new lang_string('minutes'),
 123              60 * 30 => '30 ' . new lang_string('minutes'),
 124              60 * 60 => '1 ' . new lang_string('hour'),
 125              60 * 60 * 2 => '2 ' . new lang_string('hours'),
 126              60 * 60 * 3 => '3 ' . new lang_string('hours'),
 127              60 * 60 * 4 => '4 ' . new lang_string('hours'),
 128              60 * 60 * 5 => '5 ' . new lang_string('hours'),
 129              60 * 60 * 6 => '6 ' . new lang_string('hours'),
 130              60 * 60 * 7 => '7 ' . new lang_string('hours'),
 131              60 * 60 * 8 => '8 ' . new lang_string('hours'),
 132          ]
 133      ));
 134      $temp->add(new admin_setting_configtext('statsruntimedays', new lang_string('statsruntimedays', 'admin'),
 135          new lang_string('configstatsruntimedays', 'admin'), 31, PARAM_INT));
 136      $temp->add(new admin_setting_configtext('statsuserthreshold', new lang_string('statsuserthreshold', 'admin'),
 137          new lang_string('configstatsuserthreshold', 'admin'), 0, PARAM_INT));
 138      $ADMIN->add('server', $temp);
 139  
 140      // HTTP.
 141      $temp = new admin_settingpage('http', new lang_string('http', 'admin'));
 142      $temp->add(new admin_setting_configcheckbox('slasharguments', new lang_string('slasharguments', 'admin'),
 143          new lang_string('configslasharguments', 'admin'), 1));
 144      $temp->add(new admin_setting_heading('reverseproxy', new lang_string('reverseproxy', 'admin'), '', ''));
 145      $options = [
 146          0 => 'HTTP_CLIENT_IP, HTTP_X_FORWARDED_FOR, REMOTE_ADDR',
 147          GETREMOTEADDR_SKIP_HTTP_CLIENT_IP => 'HTTP_X_FORWARDED_FOR, REMOTE_ADDR',
 148          GETREMOTEADDR_SKIP_HTTP_X_FORWARDED_FOR => 'HTTP_CLIENT, REMOTE_ADDR',
 149          GETREMOTEADDR_SKIP_HTTP_X_FORWARDED_FOR | GETREMOTEADDR_SKIP_HTTP_CLIENT_IP => 'REMOTE_ADDR'
 150      ];
 151      $temp->add(new admin_setting_configselect('getremoteaddrconf', new lang_string('getremoteaddrconf', 'admin'),
 152          new lang_string('configgetremoteaddrconf', 'admin'),
 153          GETREMOTEADDR_SKIP_HTTP_X_FORWARDED_FOR | GETREMOTEADDR_SKIP_HTTP_CLIENT_IP, $options));
 154      $temp->add(new admin_setting_configtext('reverseproxyignore', new lang_string('reverseproxyignore', 'admin'),
 155          new lang_string('configreverseproxyignore', 'admin'), ''));
 156  
 157      $temp->add(new admin_setting_heading('webproxy', new lang_string('webproxy', 'admin'),
 158          new lang_string('webproxyinfo', 'admin')));
 159      $temp->add(new admin_setting_configtext('proxyhost', new lang_string('proxyhost', 'admin'),
 160          new lang_string('configproxyhost', 'admin'), '', PARAM_HOST));
 161      $temp->add(new admin_setting_configtext('proxyport', new lang_string('proxyport', 'admin'),
 162          new lang_string('configproxyport', 'admin'), 0, PARAM_INT));
 163      $options = ['HTTP' => 'HTTP'];
 164      if (defined('CURLPROXY_SOCKS5')) {
 165          $options['SOCKS5'] = 'SOCKS5';
 166      }
 167      $temp->add(new admin_setting_configselect('proxytype', new lang_string('proxytype', 'admin'),
 168          new lang_string('configproxytype', 'admin'), 'HTTP', $options));
 169      $temp->add(new admin_setting_configtext('proxyuser', new lang_string('proxyuser', 'admin'),
 170          new lang_string('configproxyuser', 'admin'), ''));
 171      $temp->add(new admin_setting_configpasswordunmask('proxypassword', new lang_string('proxypassword', 'admin'),
 172          new lang_string('configproxypassword', 'admin'), ''));
 173      $temp->add(new admin_setting_configtext('proxybypass', new lang_string('proxybypass', 'admin'),
 174          new lang_string('configproxybypass', 'admin'), 'localhost, 127.0.0.1'));
 175      $ADMIN->add('server', $temp);
 176  
 177      $temp = new admin_settingpage('maintenancemode', new lang_string('sitemaintenancemode', 'admin'));
 178      $options = [0 => new lang_string('disable'), 1 => new lang_string('enable')];
 179      $temp->add(new admin_setting_configselect('maintenance_enabled', new lang_string('sitemaintenancemode', 'admin'),
 180          new lang_string('helpsitemaintenance', 'admin'), 0, $options));
 181      $temp->add(new admin_setting_confightmleditor('maintenance_message', new lang_string('optionalmaintenancemessage', 'admin'),
 182          '', ''));
 183      $ADMIN->add('server', $temp);
 184  
 185      // Cleanup.
 186      $temp = new admin_settingpage('cleanup', new lang_string('cleanup', 'admin'));
 187      $temp->add(new admin_setting_configselect('deleteunconfirmed', new lang_string('deleteunconfirmed', 'admin'),
 188          new lang_string('configdeleteunconfirmed', 'admin'), 168,
 189          [
 190              0 => new lang_string('never'),
 191              168 => new lang_string('numdays', '', 7),
 192              144 => new lang_string('numdays', '', 6),
 193              120 => new lang_string('numdays', '', 5),
 194              96 => new lang_string('numdays', '', 4),
 195              72 => new lang_string('numdays', '', 3),
 196              48 => new lang_string('numdays', '', 2),
 197              24 => new lang_string('numdays', '', 1),
 198              12 => new lang_string('numhours', '', 12),
 199              6 => new lang_string('numhours', '', 6),
 200              1 => new lang_string('numhours', '', 1),
 201          ]
 202      ));
 203  
 204      $temp->add(new admin_setting_configselect('deleteincompleteusers', new lang_string('deleteincompleteusers', 'admin'),
 205          new lang_string('configdeleteincompleteusers', 'admin'), 0,
 206          [
 207              0 => new lang_string('never'),
 208              168 => new lang_string('numdays', '', 7),
 209              144 => new lang_string('numdays', '', 6),
 210              120 => new lang_string('numdays', '', 5),
 211              96 => new lang_string('numdays', '', 4),
 212              72 => new lang_string('numdays', '', 3),
 213              48 => new lang_string('numdays', '', 2),
 214              24 => new lang_string('numdays', '', 1),
 215          ]
 216      ));
 217  
 218      $temp->add(new admin_setting_configcheckbox('disablegradehistory', new lang_string('disablegradehistory', 'grades'),
 219          new lang_string('disablegradehistory_help', 'grades'), 0));
 220  
 221      $temp->add(new admin_setting_configselect('gradehistorylifetime', new lang_string('gradehistorylifetime', 'grades'),
 222          new lang_string('gradehistorylifetime_help', 'grades'), 0,
 223          [
 224              0 => new lang_string('neverdeletehistory', 'grades'),
 225              1000 => new lang_string('numdays', '', 1000),
 226              365 => new lang_string('numdays', '', 365),
 227              180 => new lang_string('numdays', '', 180),
 228              150 => new lang_string('numdays', '', 150),
 229              120 => new lang_string('numdays', '', 120),
 230              90 => new lang_string('numdays', '', 90),
 231              60 => new lang_string('numdays', '', 60),
 232              30 => new lang_string('numdays', '', 30),
 233          ]
 234      ));
 235  
 236      $temp->add(new admin_setting_configselect('tempdatafoldercleanup', new lang_string('tempdatafoldercleanup', 'admin'),
 237          new lang_string('configtempdatafoldercleanup', 'admin'), 168,
 238          [
 239              1 => new lang_string('numhours', '', 1),
 240              3 => new lang_string('numhours', '', 3),
 241              6 => new lang_string('numhours', '', 6),
 242              9 => new lang_string('numhours', '', 9),
 243              12 => new lang_string('numhours', '', 12),
 244              18 => new lang_string('numhours', '', 18),
 245              24 => new lang_string('numhours', '', 24),
 246              48 => new lang_string('numdays', '', 2),
 247              168 => new lang_string('numdays', '', 7),
 248          ]
 249      ));
 250  
 251      $ADMIN->add('server', $temp);
 252  
 253      $temp->add(new admin_setting_configduration('filescleanupperiod',
 254          new lang_string('filescleanupperiod', 'admin'),
 255          new lang_string('filescleanupperiod_help', 'admin'),
 256          86400));
 257  
 258      // Environment.
 259      $ADMIN->add('server', new admin_externalpage('environment', new lang_string('environment', 'admin'),
 260          "{$CFG->wwwroot}/{$CFG->admin}/environment.php"));
 261  
 262      // PHP info.
 263      $ADMIN->add('server', new admin_externalpage('phpinfo', new lang_string('phpinfo'),
 264          "{$CFG->wwwroot}/{$CFG->admin}/phpinfo.php"));
 265  
 266      // Test outgoing mail configuration (hidden, accessed via direct link from the settings page).
 267      $ADMIN->add('server', new admin_externalpage('testoutgoingmailconf', new lang_string('testoutgoingmailconf', 'admin'),
 268          new moodle_url('/admin/testoutgoingmailconf.php'), 'moodle/site:config', true));
 269  
 270      // Performance.
 271      $temp = new admin_settingpage('performance', new lang_string('performance', 'admin'));
 272  
 273      // Memory limit options for large administration tasks.
 274      $memoryoptions = [
 275          '64M' => '64M',
 276          '128M' => '128M',
 277          '256M' => '256M',
 278          '512M' => '512M',
 279          '1024M' => '1024M',
 280          '2048M' => '2048M',
 281      ];
 282  
 283      // Allow larger memory usage for 64-bit sites only.
 284      if (PHP_INT_SIZE === 8) {
 285          $memoryoptions['3072M'] = '3072M';
 286          $memoryoptions['4096M'] = '4096M';
 287      }
 288  
 289      $temp->add(new admin_setting_configselect('extramemorylimit', new lang_string('extramemorylimit', 'admin'),
 290          new lang_string('configextramemorylimit', 'admin'), '512M', $memoryoptions));
 291  
 292      $temp->add(new admin_setting_configtext('maxtimelimit', new lang_string('maxtimelimit', 'admin'),
 293          new lang_string('maxtimelimit_desc', 'admin'), 0, PARAM_INT));
 294  
 295      $temp->add(new admin_setting_configtext('curlcache', new lang_string('curlcache', 'admin'),
 296          new lang_string('configcurlcache', 'admin'), 120, PARAM_INT));
 297  
 298      $temp->add(new admin_setting_configtext('curltimeoutkbitrate', new lang_string('curltimeoutkbitrate', 'admin'),
 299          new lang_string('curltimeoutkbitrate_help', 'admin'), 56, PARAM_INT));
 300  
 301      $ADMIN->add('server', $temp);
 302  
 303      // Tasks.
 304      $ADMIN->add('server', new admin_category('taskconfig', new lang_string('taskadmintitle', 'admin')));
 305  
 306      // Task processing.
 307      $temp = new admin_settingpage('taskprocessing', new lang_string('taskprocessing', 'admin'));
 308  
 309      $setting = new admin_setting_configcheckbox(
 310          'cron_enabled',
 311          new lang_string('cron_enabled', 'admin'),
 312          new lang_string('cron_enabled_desc', 'admin'),
 313          1
 314      );
 315      $setting->set_updatedcallback('theme_reset_static_caches');
 316      $temp->add($setting);
 317  
 318      $temp->add(
 319          new admin_setting_configtext(
 320              'task_scheduled_concurrency_limit',
 321              new lang_string('task_scheduled_concurrency_limit', 'admin'),
 322              new lang_string('task_scheduled_concurrency_limit_desc', 'admin'),
 323              3,
 324              PARAM_INT
 325          )
 326      );
 327  
 328      $temp->add(
 329          new admin_setting_configduration(
 330              'task_scheduled_max_runtime',
 331              new lang_string('task_scheduled_max_runtime', 'admin'),
 332              new lang_string('task_scheduled_max_runtime_desc', 'admin'),
 333              30 * MINSECS
 334          )
 335      );
 336  
 337      $temp->add(
 338          new admin_setting_configtext(
 339              'task_adhoc_concurrency_limit',
 340              new lang_string('task_adhoc_concurrency_limit', 'admin'),
 341              new lang_string('task_adhoc_concurrency_limit_desc', 'admin'),
 342              3,
 343              PARAM_INT
 344          )
 345      );
 346  
 347      $temp->add(
 348          new admin_setting_configduration(
 349              'task_adhoc_max_runtime',
 350              new lang_string('task_adhoc_max_runtime', 'admin'),
 351              new lang_string('task_adhoc_max_runtime_desc', 'admin'),
 352              30 * MINSECS
 353          )
 354      );
 355      $ADMIN->add('taskconfig', $temp);
 356  
 357      // Task log configuration.
 358      $temp = new admin_settingpage('tasklogging', new lang_string('tasklogging', 'admin'));
 359      $temp->add(
 360          new admin_setting_configselect(
 361              'task_logmode',
 362              new lang_string('task_logmode', 'admin'),
 363              new lang_string('task_logmode_desc', 'admin'),
 364              \core\task\logmanager::MODE_ALL,
 365              [
 366                  \core\task\logmanager::MODE_ALL => new lang_string('task_logmode_all', 'admin'),
 367                  \core\task\logmanager::MODE_FAILONLY => new lang_string('task_logmode_failonly', 'admin'),
 368                  \core\task\logmanager::MODE_NONE => new lang_string('task_logmode_none', 'admin'),
 369              ]
 370          )
 371      );
 372      $temp->add(
 373          new admin_setting_configcheckbox(
 374              'task_logtostdout',
 375              new lang_string('task_logtostdout', 'admin'),
 376              new lang_string('task_logtostdout_desc', 'admin'),
 377              1
 378          )
 379      );
 380  
 381      if (\core\task\logmanager::uses_standard_settings()) {
 382          $temp->add(
 383              new admin_setting_configduration(
 384                  'task_logretention',
 385                  new \lang_string('task_logretention', 'admin'),
 386                  new \lang_string('task_logretention_desc', 'admin'),
 387                  28 * DAYSECS
 388              )
 389          );
 390  
 391          $temp->add(
 392              new admin_setting_configtext(
 393                  'task_logretainruns',
 394                  new \lang_string('task_logretainruns', 'admin'),
 395                  new \lang_string('task_logretainruns_desc', 'admin'),
 396                  20,
 397                  PARAM_INT
 398              )
 399          );
 400      }
 401      $ADMIN->add('taskconfig', $temp);
 402  
 403      // Task logs.
 404      if (\core\task\logmanager::uses_standard_settings()) {
 405          $ADMIN->add('taskconfig', new admin_externalpage(
 406              'tasklogs',
 407              new lang_string('tasklogs', 'admin'),
 408              "{$CFG->wwwroot}/{$CFG->admin}/tasklogs.php"
 409          ));
 410      }
 411  
 412      // Email.
 413      $ADMIN->add('server', new admin_category('email', new lang_string('categoryemail', 'admin')));
 414  
 415      // Outgoing mail configuration.
 416      $temp = new admin_settingpage('outgoingmailconfig', new lang_string('outgoingmailconfig', 'admin'));
 417  
 418      $temp->add(new admin_setting_heading('smtpheading', new lang_string('smtp', 'admin'),
 419          new lang_string('smtpdetail', 'admin')));
 420  
 421      $temp->add(new admin_setting_configtext('smtphosts', new lang_string('smtphosts', 'admin'),
 422          new lang_string('configsmtphosts', 'admin'), '', PARAM_RAW));
 423  
 424      $options = [
 425          '' => new lang_string('none', 'admin'),
 426          'ssl' => 'SSL',
 427          'tls' => 'TLS',
 428      ];
 429  
 430      $temp->add(new admin_setting_configselect('smtpsecure', new lang_string('smtpsecure', 'admin'),
 431          new lang_string('configsmtpsecure', 'admin'), '', $options));
 432  
 433      $authtypeoptions = [
 434          'LOGIN' => 'LOGIN',
 435          'PLAIN' => 'PLAIN',
 436          'NTLM' => 'NTLM',
 437          'CRAM-MD5' => 'CRAM-MD5',
 438      ];
 439  
 440      $temp->add(new admin_setting_configselect('smtpauthtype', new lang_string('smtpauthtype', 'admin'),
 441          new lang_string('configsmtpauthtype', 'admin'), 'LOGIN', $authtypeoptions));
 442  
 443      $temp->add(new admin_setting_configtext('smtpuser', new lang_string('smtpuser', 'admin'),
 444          new lang_string('configsmtpuser', 'admin'), '', PARAM_NOTAGS));
 445  
 446      $temp->add(new admin_setting_configpasswordunmask('smtppass', new lang_string('smtppass', 'admin'),
 447          new lang_string('configsmtpuser', 'admin'), ''));
 448  
 449      $temp->add(new admin_setting_configtext('smtpmaxbulk', new lang_string('smtpmaxbulk', 'admin'),
 450          new lang_string('configsmtpmaxbulk', 'admin'), 1, PARAM_INT));
 451  
 452      $temp->add(new admin_setting_heading('noreplydomainheading', new lang_string('noreplydomain', 'admin'),
 453          new lang_string('noreplydomaindetail', 'admin')));
 454  
 455      $temp->add(new admin_setting_configtext('noreplyaddress', new lang_string('noreplyaddress', 'admin'),
 456          new lang_string('confignoreplyaddress', 'admin'), 'noreply@' . get_host_from_url($CFG->wwwroot), PARAM_EMAIL));
 457  
 458      $temp->add(new admin_setting_configtextarea('allowedemaildomains',
 459          new lang_string('allowedemaildomains', 'admin'),
 460          new lang_string('configallowedemaildomains', 'admin'),
 461          ''));
 462  
 463      $temp->add(new admin_setting_heading('divertallemailsheading', new lang_string('divertallemails', 'admin'),
 464          new lang_string('divertallemailsdetail', 'admin')));
 465      $temp->add(new admin_setting_configtext('divertallemailsto',
 466          new lang_string('divertallemailsto', 'admin'),
 467          new lang_string('divertallemailsto_desc', 'admin'),
 468          ''));
 469      $temp->add(new admin_setting_configtextarea('divertallemailsexcept',
 470          new lang_string('divertallemailsexcept', 'admin'),
 471          new lang_string('divertallemailsexcept_desc', 'admin'),
 472          '', PARAM_RAW, '50', '4'));
 473  
 474      $noreplyaddress = isset($CFG->noreplyaddress) ? $CFG->noreplyaddress : 'noreply@example.com';
 475      $dkimdomain = substr(strrchr($noreplyaddress, "@"), 1);
 476      $dkimselector = empty($CFG->emaildkimselector) ? '[selector]' : $CFG->emaildkimselector;
 477      $pempath = "\$CFG->dataroot/dkim/{$dkimdomain}/{$dkimselector}.private";
 478      $temp->add(new admin_setting_heading('emaildkim', new lang_string('emaildkim', 'admin'),
 479          new lang_string('emaildkiminfo', 'admin', ['path' => $pempath, 'docs' => \get_docs_url('Mail_configuration#DKIM')])));
 480      $temp->add(new admin_setting_configtext('emaildkimselector', new lang_string('emaildkimselector', 'admin'),
 481          new lang_string('configemaildkimselector', 'admin'), '', PARAM_FILE));
 482  
 483      $url = new moodle_url('/admin/testoutgoingmailconf.php');
 484      $link = html_writer::link($url, get_string('testoutgoingmailconf', 'admin'));
 485      $temp->add(new admin_setting_heading('testoutgoinmailc', new lang_string('testoutgoingmailconf', 'admin'),
 486          new lang_string('testoutgoingmaildetail', 'admin', $link)));
 487  
 488      $temp->add(new admin_setting_heading('emaildoesnotfit', new lang_string('doesnotfit', 'admin'),
 489          new lang_string('doesnotfitdetail', 'admin')));
 490  
 491      $charsets = get_list_of_charsets();
 492      unset($charsets['UTF-8']);
 493      $options = [
 494          '0' => 'UTF-8',
 495      ];
 496      $options = array_merge($options, $charsets);
 497      $temp->add(new admin_setting_configselect('sitemailcharset', new lang_string('sitemailcharset', 'admin'),
 498          new lang_string('configsitemailcharset', 'admin'), '0', $options));
 499  
 500      $temp->add(new admin_setting_configcheckbox('allowusermailcharset', new lang_string('allowusermailcharset', 'admin'),
 501          new lang_string('configallowusermailcharset', 'admin'), 0));
 502  
 503      $temp->add(new admin_setting_configcheckbox('allowattachments', new lang_string('allowattachments', 'admin'),
 504          new lang_string('configallowattachments', 'admin'), 1));
 505  
 506      $options = [
 507          'LF' => 'LF',
 508          'CRLF' => 'CRLF',
 509      ];
 510      $temp->add(new admin_setting_configselect('mailnewline', new lang_string('mailnewline', 'admin'),
 511          new lang_string('configmailnewline', 'admin'), 'LF', $options));
 512  
 513      $choices = [
 514          new lang_string('never', 'admin'),
 515          new lang_string('always', 'admin'),
 516          new lang_string('onlynoreply', 'admin'),
 517      ];
 518      $temp->add(new admin_setting_configselect('emailfromvia', new lang_string('emailfromvia', 'admin'),
 519          new lang_string('configemailfromvia', 'admin'), 1, $choices));
 520  
 521      $temp->add(new admin_setting_configtext('emailsubjectprefix', new lang_string('emailsubjectprefix', 'admin'),
 522          new lang_string('configemailsubjectprefix', 'admin'), '', PARAM_RAW));
 523  
 524      $temp->add(new admin_setting_configtextarea('emailheaders', new lang_string('emailheaders', 'admin'),
 525          new lang_string('configemailheaders', 'admin'), '', PARAM_RAW, '50', '3'));
 526  
 527      $ADMIN->add('email', $temp);
 528  
 529      // Update notifications.
 530      if (empty($CFG->disableupdatenotifications)) {
 531          $temp = new admin_settingpage('updatenotifications', new lang_string('updatenotifications', 'core_admin'));
 532          $temp->add(new admin_setting_configcheckbox('updateautocheck', new lang_string('updateautocheck', 'core_admin'),
 533              new lang_string('updateautocheck_desc', 'core_admin'), 1));
 534          $temp->add(new admin_setting_configselect('updateminmaturity', new lang_string('updateminmaturity', 'core_admin'),
 535              new lang_string('updateminmaturity_desc', 'core_admin'), MATURITY_STABLE,
 536              [
 537                  MATURITY_ALPHA => new lang_string('maturity'.MATURITY_ALPHA, 'core_admin'),
 538                  MATURITY_BETA => new lang_string('maturity'.MATURITY_BETA, 'core_admin'),
 539                  MATURITY_RC => new lang_string('maturity'.MATURITY_RC, 'core_admin'),
 540                  MATURITY_STABLE => new lang_string('maturity'.MATURITY_STABLE, 'core_admin'),
 541              ]
 542          ));
 543          $temp->add(new admin_setting_configcheckbox('updatenotifybuilds', new lang_string('updatenotifybuilds', 'core_admin'),
 544              new lang_string('updatenotifybuilds_desc', 'core_admin'), 0));
 545          $ADMIN->add('server', $temp);
 546      }
 547  
 548      // Web services.
 549      $ADMIN->add('server', new admin_category('webservicesettings', new lang_string('webservices', 'webservice')));
 550  
 551      // Web services > Overview.
 552      $temp = new admin_settingpage('webservicesoverview', new lang_string('webservicesoverview', 'webservice'));
 553      $temp->add(new admin_setting_webservicesoverview());
 554      $ADMIN->add('webservicesettings', $temp);
 555  
 556      // Web services > API documentation.
 557      $ADMIN->add('webservicesettings', new admin_externalpage('webservicedocumentation', new lang_string('wsdocapi', 'webservice'),
 558          "{$CFG->wwwroot}/{$CFG->admin}/webservice/documentation.php", 'moodle/site:config', false));
 559  
 560      // Web services > External services.
 561      $temp = new admin_settingpage('externalservices', new lang_string('externalservices', 'webservice'));
 562  
 563      $temp->add(new admin_setting_heading('manageserviceshelpexplaination', new lang_string('information', 'webservice'),
 564          new lang_string('servicehelpexplanation', 'webservice')));
 565  
 566      $temp->add(new admin_setting_manageexternalservices());
 567  
 568      $ADMIN->add('webservicesettings', $temp);
 569  
 570      $ADMIN->add('webservicesettings', new admin_externalpage('externalservice', new lang_string('editaservice', 'webservice'),
 571          "{$CFG->wwwroot}/{$CFG->admin}/webservice/service.php", 'moodle/site:config', true));
 572  
 573      $ADMIN->add('webservicesettings', new admin_externalpage('externalservicefunctions',
 574          new lang_string('externalservicefunctions', 'webservice'), "{$CFG->wwwroot}/{$CFG->admin}/webservice/service_functions.php",
 575          'moodle/site:config', true));
 576  
 577      $ADMIN->add('webservicesettings', new admin_externalpage('externalserviceusers',
 578          new lang_string('externalserviceusers', 'webservice'), "{$CFG->wwwroot}/{$CFG->admin}/webservice/service_users.php",
 579          'moodle/site:config', true));
 580  
 581      $ADMIN->add('webservicesettings', new admin_externalpage('externalserviceusersettings',
 582          new lang_string('serviceusersettings', 'webservice'), "{$CFG->wwwroot}/{$CFG->admin}/webservice/service_user_settings.php",
 583          'moodle/site:config', true));
 584  
 585      // Web services > Manage protocols.
 586      $temp = new admin_settingpage('webserviceprotocols', new lang_string('manageprotocols', 'webservice'));
 587      $temp->add(new admin_setting_managewebserviceprotocols());
 588      if (empty($CFG->enablewebservices)) {
 589          $temp->add(new admin_setting_heading('webservicesaredisabled', '', new lang_string('disabledwarning', 'webservice')));
 590      }
 591  
 592      // We cannot use $OUTPUT->doc_link() this early, we would lose the ability to set the page layout on all admin pages.
 593      $url = new moodle_url(get_docs_url('How_to_get_a_security_key'));
 594      $wsdoclink = html_writer::link($url, new lang_string('supplyinfo', 'webservice'), ['target' => '_blank']);
 595      $temp->add(new admin_setting_configcheckbox('enablewsdocumentation', new lang_string('enablewsdocumentation', 'admin'),
 596          new lang_string('configenablewsdocumentation', 'admin', $wsdoclink), false));
 597  
 598      $ADMIN->add('webservicesettings', $temp);
 599  
 600      $plugins = core_plugin_manager::instance()->get_plugins_of_type('webservice');
 601      core_collator::asort_objects_by_property($plugins, 'displayname');
 602      foreach ($plugins as $plugin) {
 603          /** @var \core\plugininfo\webservice $plugin */
 604          $plugin->load_settings($ADMIN, 'webservicesettings', $hassiteconfig);
 605      }
 606  
 607      // Web services > Manage tokens.
 608      $ADMIN->add('webservicesettings', new admin_externalpage('webservicetokens', new lang_string('managetokens', 'webservice'),
 609          new moodle_url('/admin/webservice/tokens.php')));
 610  }