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.
  • /admin/ -> qtypes.php (source)

    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 types.
      20   *
      21   * @package    moodlecore
      22   * @subpackage questionbank
      23   * @copyright  2008 Tim Hunt
      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  admin_externalpage_setup('manageqtypes');
      34  
      35  $systemcontext = context_system::instance();
      36  require_capability('moodle/question:config', $systemcontext);
      37  $canviewreports = has_capability('report/questioninstances:view', $systemcontext);
      38  
      39  $thispageurl = new moodle_url('/admin/qtypes.php');
      40  
      41  $qtypes = question_bank::get_all_qtypes();
      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("
      46          SELECT qtype, COUNT(1) as numquestions, SUM(hidden) as numhidden
      47          FROM {question} GROUP BY qtype", array());
      48  $needed = array();
      49  foreach ($qtypes as $qtypename => $qtype) {
      50      if (!isset($counts[$qtypename])) {
      51          $counts[$qtypename] = new stdClass;
      52          $counts[$qtypename]->numquestions = 0;
      53          $counts[$qtypename]->numhidden = 0;
      54      }
      55      $needed[$qtypename] = $counts[$qtypename]->numquestions > 0 ||
      56              $pluginmanager->other_plugins_that_require($qtype->plugin_name());
      57      $counts[$qtypename]->numquestions -= $counts[$qtypename]->numhidden;
      58  }
      59  $needed['missingtype'] = true; // The system needs the missing question type.
      60  foreach ($counts as $qtypename => $count) {
      61      if (!isset($qtypes[$qtypename])) {
      62          $counts['missingtype']->numquestions += $count->numquestions - $count->numhidden;
      63          $counts['missingtype']->numhidden += $count->numhidden;
      64      }
      65  }
      66  
      67  // Work of the correct sort order.
      68  $config = get_config('question');
      69  $sortedqtypes = array();
      70  foreach ($qtypes as $qtypename => $qtype) {
      71      $sortedqtypes[$qtypename] = $qtype->local_name();
      72  }
      73  $sortedqtypes = question_bank::sort_qtype_array($sortedqtypes, $config);
      74  
      75  // Process actions ============================================================
      76  
      77  // Disable.
      78  if (($disable = optional_param('disable', '', PARAM_PLUGIN)) && confirm_sesskey()) {
      79      if (!isset($qtypes[$disable])) {
      80          print_error('unknownquestiontype', 'question', $thispageurl, $disable);
      81      }
      82  
      83      set_config($disable . '_disabled', 1, 'question');
      84      redirect($thispageurl);
      85  }
      86  
      87  // Enable.
      88  if (($enable = optional_param('enable', '', PARAM_PLUGIN)) && confirm_sesskey()) {
      89      if (!isset($qtypes[$enable])) {
      90          print_error('unknownquestiontype', 'question', $thispageurl, $enable);
      91      }
      92  
      93      if (!$qtypes[$enable]->menu_name()) {
      94          print_error('cannotenable', 'question', $thispageurl, $enable);
      95      }
      96  
      97      unset_config($enable . '_disabled', 'question');
      98      redirect($thispageurl);
      99  }
     100  
     101  // Move up in order.
     102  if (($up = optional_param('up', '', PARAM_PLUGIN)) && confirm_sesskey()) {
     103      if (!isset($qtypes[$up])) {
     104          print_error('unknownquestiontype', 'question', $thispageurl, $up);
     105      }
     106  
     107      $neworder = question_reorder_qtypes($sortedqtypes, $up, -1);
     108      question_save_qtype_order($neworder, $config);
     109      redirect($thispageurl);
     110  }
     111  
     112  // Move down in order.
     113  if (($down = optional_param('down', '', PARAM_PLUGIN)) && confirm_sesskey()) {
     114      if (!isset($qtypes[$down])) {
     115          print_error('unknownquestiontype', 'question', $thispageurl, $down);
     116      }
     117  
     118      $neworder = question_reorder_qtypes($sortedqtypes, $down, +1);
     119      question_save_qtype_order($neworder, $config);
     120      redirect($thispageurl);
     121  }
     122  
     123  // End of process actions ==================================================
     124  
     125  // Print the page heading.
     126  echo $OUTPUT->header();
     127  echo $OUTPUT->heading(get_string('manageqtypes', 'admin'));
     128  
     129  // Set up the table.
     130  $table = new flexible_table('qtypeadmintable');
     131  $table->define_baseurl($thispageurl);
     132  $table->define_columns(array('questiontype', 'numquestions', 'version', 'requires',
     133          'availableto', 'uninstall', 'settings'));
     134  $table->define_headers(array(get_string('questiontype', 'question'), get_string('numquestions', 'question'),
     135          get_string('version'), get_string('requires', 'admin'), get_string('availableq', 'question'),
     136          get_string('settings'), get_string('uninstallplugin', 'core_admin')));
     137  $table->set_attribute('id', 'qtypes');
     138  $table->set_attribute('class', 'admintable generaltable');
     139  $table->setup();
     140  
     141  // Add a row for each question type.
     142  $createabletypes = question_bank::get_creatable_qtypes();
     143  foreach ($sortedqtypes as $qtypename => $localname) {
     144      $qtype = $qtypes[$qtypename];
     145      $row = array();
     146  
     147      // Question icon and name.
     148      $fakequestion = new stdClass;
     149      $fakequestion->qtype = $qtypename;
     150      $icon = print_question_icon($fakequestion, true);
     151      $row[] = $icon . ' ' . $localname;
     152  
     153      // Number of questions of this type.
     154      if ($counts[$qtypename]->numquestions + $counts[$qtypename]->numhidden > 0) {
     155          if ($counts[$qtypename]->numhidden > 0) {
     156              $strcount = get_string('numquestionsandhidden', 'question', $counts[$qtypename]);
     157          } else {
     158              $strcount = $counts[$qtypename]->numquestions;
     159          }
     160          if ($canviewreports) {
     161              $row[] = html_writer::link(new moodle_url('/report/questioninstances/index.php',
     162                      array('qtype' => $qtypename)), $strcount, array('title' => get_string('showdetails', 'admin')));
     163          } else {
     164              $strcount;
     165          }
     166      } else {
     167          $row[] = 0;
     168      }
     169  
     170      // Question version number.
     171      $version = get_config('qtype_' . $qtypename, 'version');
     172      if ($version) {
     173          $row[] = $version;
     174      } else {
     175          $row[] = html_writer::tag('span', get_string('nodatabase', 'admin'), array('class' => 'text-muted'));
     176      }
     177  
     178      // Other question types required by this one.
     179      $plugin = $pluginmanager->get_plugin_info($qtype->plugin_name());
     180      $requiredtypes = $plugin->get_other_required_plugins();
     181      $strtypes = array();
     182      if (!empty($requiredtypes)) {
     183          foreach ($requiredtypes as $required => $notused) {
     184              $strtypes[] = $pluginmanager->plugin_name($required);
     185          }
     186          $row[] = implode(', ', $strtypes);
     187      } else {
     188          $row[] = '';
     189      }
     190  
     191      // Are people allowed to create new questions of this type?
     192      $rowclass = '';
     193      if ($qtype->menu_name()) {
     194          $createable = isset($createabletypes[$qtypename]);
     195          $icons = question_types_enable_disable_icons($qtypename, $createable);
     196          if (!$createable) {
     197              $rowclass = 'dimmed_text';
     198          }
     199      } else {
     200          $icons = $OUTPUT->spacer();
     201      }
     202  
     203      // Move icons.
     204      $icons .= question_type_icon_html('up', $qtypename, 't/up', get_string('up'), '');
     205      $icons .= question_type_icon_html('down', $qtypename, 't/down', get_string('down'), '');
     206      $row[] = $icons;
     207  
     208      // Settings link, if available.
     209      $settings = admin_get_root()->locate('qtypesetting' . $qtypename);
     210      if ($settings instanceof admin_externalpage) {
     211          $row[] = html_writer::link($settings->url, get_string('settings'));
     212      } else if ($settings instanceof admin_settingpage) {
     213          $row[] = html_writer::link(new moodle_url('/admin/settings.php',
     214                  array('section' => 'qtypesetting' . $qtypename)), get_string('settings'));
     215      } else {
     216          $row[] = '';
     217      }
     218  
     219      // Uninstall link, if available.
     220      if ($needed[$qtypename]) {
     221          $row[] = '';
     222      } else {
     223          $uninstallurl = core_plugin_manager::instance()->get_uninstall_url('qtype_'.$qtypename, 'manage');
     224          if ($uninstallurl) {
     225              $row[] = html_writer::link($uninstallurl, get_string('uninstallplugin', 'core_admin'),
     226                  array('title' => get_string('uninstallqtype', 'question')));
     227          }
     228      }
     229  
     230      $table->add_data($row, $rowclass);
     231  }
     232  
     233  $table->finish_output();
     234  
     235  echo $OUTPUT->footer();
     236  
     237  function question_types_enable_disable_icons($qtypename, $createable) {
     238      if ($createable) {
     239          return question_type_icon_html('disable', $qtypename, 't/hide',
     240                  get_string('enabled', 'question'), get_string('disable'));
     241      } else {
     242          return question_type_icon_html('enable', $qtypename, 't/show',
     243                  get_string('disabled', 'question'), get_string('enable'));
     244      }
     245  }
     246  
     247  function question_type_icon_html($action, $qtypename, $icon, $alt, $tip) {
     248      global $OUTPUT;
     249      return $OUTPUT->action_icon(new moodle_url('/admin/qtypes.php',
     250              array($action => $qtypename, 'sesskey' => sesskey())),
     251              new pix_icon($icon, $alt, 'moodle', array('title' => '', 'class' => 'iconsmall')),
     252              null, array('title' => $tip));
     253  }
     254