Search moodle.org's
Developer Documentation

  • Bug fixes for general core bugs in 3.10.x will end 8 November 2021 (12 months).
  • Bug fixes for security issues in 3.10.x will end 9 May 2022 (18 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 310 and 34] [Versions 310 and 35] [Versions 310 and 36] [Versions 310 and 37] [Versions 310 and 38] [Versions 34 and 310] [Versions 35 and 310] [Versions 36 and 310] [Versions 37 and 310] [Versions 38 and 310]

       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   * Allows the admin to manage question behaviours.
      20   *
      21   * @package    moodlecore
      22   * @subpackage questionengine
      23   * @copyright  2011 The Open University
      24   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
      25   */
      26  
      27  
      28  require_once(__DIR__ . '/../config.php');
      29  require_once($CFG->libdir . '/questionlib.php');
      30  require_once($CFG->libdir . '/adminlib.php');
      31  require_once($CFG->libdir . '/tablelib.php');
      32  
      33  // Check permissions.
      34  require_login(null, false);
      35  $systemcontext = context_system::instance();
      36  require_capability('moodle/question:config', $systemcontext);
      37  
      38  admin_externalpage_setup('manageqbehaviours');
      39  $thispageurl = new moodle_url('/admin/qbehaviours.php');
      40  
      41  $behaviours = core_component::get_plugin_list('qbehaviour');
      42  $pluginmanager = core_plugin_manager::instance();
      43  
      44  // Get some data we will need - question counts and which types are needed.
      45  $counts = $DB->get_records_sql_menu("
      46          SELECT behaviour, COUNT(1)
      47          FROM {question_attempts} GROUP BY behaviour");
      48  $needed = array();
      49  $archetypal = array();
      50  foreach ($behaviours as $behaviour => $notused) {
      51      if (!array_key_exists($behaviour, $counts)) {
      52          $counts[$behaviour] = 0;
      53      }
      54      $needed[$behaviour] = ($counts[$behaviour] > 0) ||
      55              $pluginmanager->other_plugins_that_require('qbehaviour_' . $behaviour);
      56      $archetypal[$behaviour] = question_engine::is_behaviour_archetypal($behaviour);
      57  }
      58  foreach ($counts as $behaviour => $count) {
      59      if (!array_key_exists($behaviour, $behaviours)) {
      60          $counts['missing'] += $count;
      61      }
      62  }
      63  $needed['missing'] = true;
      64  
      65  // Work of the correct sort order.
      66  $config = get_config('question');
      67  $sortedbehaviours = array();
      68  foreach ($behaviours as $behaviour => $notused) {
      69      $sortedbehaviours[$behaviour] = question_engine::get_behaviour_name($behaviour);
      70  }
      71  if (!empty($config->behavioursortorder)) {
      72      $sortedbehaviours = question_engine::sort_behaviours($sortedbehaviours,
      73              $config->behavioursortorder, '');
      74  }
      75  
      76  if (!empty($config->disabledbehaviours)) {
      77      $disabledbehaviours = explode(',', $config->disabledbehaviours);
      78  } else {
      79      $disabledbehaviours = array();
      80  }
      81  
      82  // Process actions ============================================================
      83  
      84  // Disable.
      85  if (($disable = optional_param('disable', '', PARAM_PLUGIN)) && confirm_sesskey()) {
      86      if (!isset($behaviours[$disable])) {
      87          print_error('unknownbehaviour', 'question', $thispageurl, $disable);
      88      }
      89  
      90      if (array_search($disable, $disabledbehaviours) === false) {
      91          $disabledbehaviours[] = $disable;
      92          set_config('disabledbehaviours', implode(',', $disabledbehaviours), 'question');
      93      }
      94      core_plugin_manager::reset_caches();
      95      redirect($thispageurl);
      96  }
      97  
      98  // Enable.
      99  if (($enable = optional_param('enable', '', PARAM_PLUGIN)) && confirm_sesskey()) {
     100      if (!isset($behaviours[$enable])) {
     101          print_error('unknownbehaviour', 'question', $thispageurl, $enable);
     102      }
     103  
     104      if (!$archetypal[$enable]) {
     105          print_error('cannotenablebehaviour', 'question', $thispageurl, $enable);
     106      }
     107  
     108      if (($key = array_search($enable, $disabledbehaviours)) !== false) {
     109          unset($disabledbehaviours[$key]);
     110          set_config('disabledbehaviours', implode(',', $disabledbehaviours), 'question');
     111      }
     112      core_plugin_manager::reset_caches();
     113      redirect($thispageurl);
     114  }
     115  
     116  // Move up in order.
     117  if (($up = optional_param('up', '', PARAM_PLUGIN)) && confirm_sesskey()) {
     118      if (!isset($behaviours[$up])) {
     119          print_error('unknownbehaviour', 'question', $thispageurl, $up);
     120      }
     121  
     122      // This function works fine for behaviours, as well as qtypes.
     123      $neworder = question_reorder_qtypes($sortedbehaviours, $up, -1);
     124      set_config('behavioursortorder', implode(',', $neworder), 'question');
     125      redirect($thispageurl);
     126  }
     127  
     128  // Move down in order.
     129  if (($down = optional_param('down', '', PARAM_PLUGIN)) && confirm_sesskey()) {
     130      if (!isset($behaviours[$down])) {
     131          print_error('unknownbehaviour', 'question', $thispageurl, $down);
     132      }
     133  
     134      // This function works fine for behaviours, as well as qtypes.
     135      $neworder = question_reorder_qtypes($sortedbehaviours, $down, +1);
     136      set_config('behavioursortorder', implode(',', $neworder), 'question');
     137      redirect($thispageurl);
     138  }
     139  
     140  // End of process actions ==================================================
     141  
     142  // Print the page heading.
     143  echo $OUTPUT->header();
     144  echo $OUTPUT->heading(get_string('manageqbehaviours', 'admin'));
     145  
     146  // Set up the table.
     147  $table = new flexible_table('qbehaviouradmintable');
     148  $table->define_baseurl($thispageurl);
     149  $table->define_columns(array('behaviour', 'numqas', 'version', 'requires',
     150          'available', 'uninstall'));
     151  $table->define_headers(array(get_string('behaviour', 'question'), get_string('numqas', 'question'),
     152          get_string('version'), get_string('requires', 'admin'),
     153          get_string('availableq', 'question'), get_string('uninstallplugin', 'core_admin')));
     154  $table->set_attribute('id', 'qbehaviours');
     155  $table->set_attribute('class', 'generaltable admintable');
     156  $table->setup();
     157  
     158  // Add a row for each question type.
     159  foreach ($sortedbehaviours as $behaviour => $behaviourname) {
     160      $row = array();
     161  
     162      // Question icon and name.
     163      $row[] = $behaviourname;
     164  
     165      // Count
     166      $row[] = $counts[$behaviour];
     167  
     168      // Question version number.
     169      $version = get_config('qbehaviour_' . $behaviour, 'version');
     170      if ($version) {
     171          $row[] = $version;
     172      } else {
     173          $row[] = html_writer::tag('span', get_string('nodatabase', 'admin'), array('class' => 'text-muted'));
     174      }
     175  
     176      // Other question types required by this one.
     177      $plugin = $pluginmanager->get_plugin_info('qbehaviour_' . $behaviour);
     178      $required = $plugin->get_other_required_plugins();
     179      if (!empty($required)) {
     180          $strrequired = array();
     181          foreach ($required as $component => $notused) {
     182              $strrequired[] = $pluginmanager->plugin_name($component);
     183          }
     184          $row[] = implode(', ', $strrequired);
     185      } else {
     186          $row[] = '';
     187      }
     188  
     189      // Are people allowed to select this behaviour?
     190      $rowclass = '';
     191      if ($archetypal[$behaviour]) {
     192          $enabled = array_search($behaviour, $disabledbehaviours) === false;
     193          $icons = question_behaviour_enable_disable_icons($behaviour, $enabled);
     194          if (!$enabled) {
     195              $rowclass = 'dimmed_text';
     196          }
     197      } else {
     198          $icons = $OUTPUT->spacer(array('class' => 'iconsmall'));
     199      }
     200  
     201      // Move icons.
     202      $icons .= question_behaviour_icon_html('up', $behaviour, 't/up', get_string('up'), null);
     203      $icons .= question_behaviour_icon_html('down', $behaviour, 't/down', get_string('down'), null);
     204      $row[] = $icons;
     205  
     206      // Delete link, if available.
     207      if ($needed[$behaviour]) {
     208          $row[] = '';
     209      } else {
     210          $uninstallurl = core_plugin_manager::instance()->get_uninstall_url('qbehaviour_'.$behaviour, 'manage');
     211          if ($uninstallurl) {
     212              $row[] = html_writer::link($uninstallurl, get_string('uninstallplugin', 'core_admin'),
     213                  array('title' => get_string('uninstallbehaviour', 'question')));
     214          }
     215      }
     216  
     217      $table->add_data($row, $rowclass);
     218  }
     219  
     220  $table->finish_output();
     221  
     222  echo $OUTPUT->footer();
     223  
     224  function question_behaviour_enable_disable_icons($behaviour, $enabled) {
     225      if ($enabled) {
     226          return question_behaviour_icon_html('disable', $behaviour, 't/hide',
     227                  get_string('enabled', 'question'), get_string('disable'));
     228      } else {
     229          return question_behaviour_icon_html('enable', $behaviour, 't/show',
     230                  get_string('disabled', 'question'), get_string('enable'));
     231      }
     232  }
     233  
     234  function question_behaviour_icon_html($action, $behaviour, $icon, $alt, $tip) {
     235      global $OUTPUT;
     236      return $OUTPUT->action_icon(new moodle_url('/admin/qbehaviours.php',
     237              array($action => $behaviour, 'sesskey' => sesskey())),
     238              new pix_icon($icon, $alt, 'moodle', array('title' => '', 'class' => 'iconsmall')),
     239              null, array('title' => $tip));
     240  }
     241