qbehaviours.php 10.8 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?php

// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.

/**
 * Allows the admin to manage question behaviours.
 *
 * @package    moodlecore
 * @subpackage questionengine
 * @copyright  2011 The Open University
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */


require_once(dirname(__FILE__) . '/../config.php');
require_once($CFG->libdir . '/questionlib.php');
require_once($CFG->libdir . '/adminlib.php');
31
require_once($CFG->libdir . '/pluginlib.php');
32
33
34
35
require_once($CFG->libdir . '/tablelib.php');

// Check permissions.
require_login();
36
$systemcontext = context_system::instance();
37
38
39
40
41
require_capability('moodle/question:config', $systemcontext);

admin_externalpage_setup('manageqbehaviours');
$thispageurl = new moodle_url('/admin/qbehaviours.php');

42
$behaviours = core_component::get_plugin_list('qbehaviour');
43
$pluginmanager = plugin_manager::instance();
44
45
46
47
48
49
50
51
52
53
54

// Get some data we will need - question counts and which types are needed.
$counts = $DB->get_records_sql_menu("
        SELECT behaviour, COUNT(1)
        FROM {question_attempts} GROUP BY behaviour");
$needed = array();
$archetypal = array();
foreach ($behaviours as $behaviour => $notused) {
    if (!array_key_exists($behaviour, $counts)) {
        $counts[$behaviour] = 0;
    }
55
    $needed[$behaviour] = ($counts[$behaviour] > 0) ||
56
            $pluginmanager->other_plugins_that_require('qbehaviour_' . $behaviour);
57
58
59
60
    $archetypal[$behaviour] = question_engine::is_behaviour_archetypal($behaviour);
}
foreach ($counts as $behaviour => $count) {
    if (!array_key_exists($behaviour, $behaviours)) {
61
        $counts['missing'] += $count;
62
63
    }
}
64
$needed['missing'] = true;
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85

// Work of the correct sort order.
$config = get_config('question');
$sortedbehaviours = array();
foreach ($behaviours as $behaviour => $notused) {
    $sortedbehaviours[$behaviour] = question_engine::get_behaviour_name($behaviour);
}
if (!empty($config->behavioursortorder)) {
    $sortedbehaviours = question_engine::sort_behaviours($sortedbehaviours,
            $config->behavioursortorder, '');
}

if (!empty($config->disabledbehaviours)) {
    $disabledbehaviours = explode(',', $config->disabledbehaviours);
} else {
    $disabledbehaviours = array();
}

// Process actions ============================================================

// Disable.
86
if (($disable = optional_param('disable', '', PARAM_PLUGIN)) && confirm_sesskey()) {
87
88
89
90
91
92
93
94
    if (!isset($behaviours[$disable])) {
        print_error('unknownbehaviour', 'question', $thispageurl, $disable);
    }

    if (array_search($disable, $disabledbehaviours) === false) {
        $disabledbehaviours[] = $disable;
        set_config('disabledbehaviours', implode(',', $disabledbehaviours), 'question');
    }
95
    plugin_manager::reset_caches();
96
97
98
99
    redirect($thispageurl);
}

// Enable.
100
if (($enable = optional_param('enable', '', PARAM_PLUGIN)) && confirm_sesskey()) {
101
102
103
104
105
106
107
108
109
110
111
112
    if (!isset($behaviours[$enable])) {
        print_error('unknownbehaviour', 'question', $thispageurl, $enable);
    }

    if (!$archetypal[$enable]) {
        print_error('cannotenablebehaviour', 'question', $thispageurl, $enable);
    }

    if (($key = array_search($enable, $disabledbehaviours)) !== false) {
        unset($disabledbehaviours[$key]);
        set_config('disabledbehaviours', implode(',', $disabledbehaviours), 'question');
    }
113
    plugin_manager::reset_caches();
114
115
116
117
    redirect($thispageurl);
}

// Move up in order.
118
if (($up = optional_param('up', '', PARAM_PLUGIN)) && confirm_sesskey()) {
119
120
121
122
123
124
125
126
127
128
129
    if (!isset($behaviours[$up])) {
        print_error('unknownbehaviour', 'question', $thispageurl, $up);
    }

    // This function works fine for behaviours, as well as qtypes.
    $neworder = question_reorder_qtypes($sortedbehaviours, $up, -1);
    set_config('behavioursortorder', implode(',', $neworder), 'question');
    redirect($thispageurl);
}

// Move down in order.
130
if (($down = optional_param('down', '', PARAM_PLUGIN)) && confirm_sesskey()) {
131
132
133
134
135
136
137
138
139
140
141
    if (!isset($behaviours[$down])) {
        print_error('unknownbehaviour', 'question', $thispageurl, $down);
    }

    // This function works fine for behaviours, as well as qtypes.
    $neworder = question_reorder_qtypes($sortedbehaviours, $down, +1);
    set_config('behavioursortorder', implode(',', $neworder), 'question');
    redirect($thispageurl);
}

// Delete.
142
if (($delete = optional_param('delete', '', PARAM_PLUGIN)) && confirm_sesskey()) {
143
144
145
146
147
    // Check it is OK to delete this question type.
    if ($delete == 'missing') {
        print_error('cannotdeletemissingbehaviour', 'question', $thispageurl);
    }

148
    if (!isset($behaviours[$delete]) && !get_config('qbehaviour_' . $delete, 'version')) {
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
        print_error('unknownbehaviour', 'question', $thispageurl, $delete);
    }

    $behaviourname = $sortedbehaviours[$delete];
    if ($counts[$delete] > 0) {
        print_error('cannotdeletebehaviourinuse', 'question', $thispageurl, $behaviourname);
    }
    if ($needed[$delete] > 0) {
        print_error('cannotdeleteneededbehaviour', 'question', $thispageurl, $behaviourname);
    }

    // If not yet confirmed, display a confirmation message.
    if (!optional_param('confirm', '', PARAM_BOOL)) {
        echo $OUTPUT->header();
        echo $OUTPUT->heading(get_string('deletebehaviourareyousure', 'question', $behaviourname));
        echo $OUTPUT->confirm(
                get_string('deletebehaviourareyousuremessage', 'question', $behaviourname),
                new moodle_url($thispageurl, array('delete' => $delete, 'confirm' => 1)),
                $thispageurl);
        echo $OUTPUT->footer();
        exit;
    }

    // Do the deletion.
    echo $OUTPUT->header();
    echo $OUTPUT->heading(get_string('deletingbehaviour', 'question', $behaviourname));

176
    // Remove this behaviour from configurations where it might appear.
177
178
179
180
    if (($key = array_search($delete, $disabledbehaviours)) !== false) {
        unset($disabledbehaviours[$key]);
        set_config('disabledbehaviours', implode(',', $disabledbehaviours), 'question');
    }
181
    $behaviourorder = array_keys($sortedbehaviours);
182
183
184
185
186
    if (($key = array_search($delete, $behaviourorder)) !== false) {
        unset($behaviourorder[$key]);
        set_config('behavioursortorder', implode(',', $behaviourorder), 'question');
    }

187
188
    // Then uninstall the plugin.
    uninstall_plugin('qbehaviour', $delete);
189

190
    // Display a message.
191
    $a = new stdClass();
192
    $a->behaviour = $behaviourname;
193
    $a->directory = core_component::get_plugin_directory('qbehaviour', $delete);
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
    echo $OUTPUT->box(get_string('qbehaviourdeletefiles', 'question', $a), 'generalbox', 'notice');
    echo $OUTPUT->continue_button($thispageurl);
    echo $OUTPUT->footer();
    exit;
}

// End of process actions ==================================================

// Print the page heading.
echo $OUTPUT->header();
echo $OUTPUT->heading(get_string('manageqbehaviours', 'admin'));

// Set up the table.
$table = new flexible_table('qbehaviouradmintable');
$table->define_baseurl($thispageurl);
$table->define_columns(array('behaviour', 'numqas', 'version', 'requires',
        'available', 'delete'));
$table->define_headers(array(get_string('behaviour', 'question'), get_string('numqas', 'question'),
        get_string('version'), get_string('requires', 'admin'),
        get_string('availableq', 'question'), get_string('delete')));
$table->set_attribute('id', 'qbehaviours');
$table->set_attribute('class', 'generaltable generalbox boxaligncenter boxwidthwide');
$table->setup();

// Add a row for each question type.
foreach ($sortedbehaviours as $behaviour => $behaviourname) {
    $row = array();

    // Question icon and name.
    $row[] = $behaviourname;

    // Count
    $row[] = $counts[$behaviour];

    // Question version number.
    $version = get_config('qbehaviour_' . $behaviour, 'version');
    if ($version) {
        $row[] = $version;
    } else {
        $row[] = html_writer::tag('span', get_string('nodatabase', 'admin'), array('class' => 'disabled'));
    }

    // Other question types required by this one.
237
238
239
240
241
242
    $plugin = $pluginmanager->get_plugin_info('qbehaviour_' . $behaviour);
    $required = $plugin->get_other_required_plugins();
    if (!empty($required)) {
        $strrequired = array();
        foreach ($required as $component => $notused) {
            $strrequired[] = $pluginmanager->plugin_name($component);
243
        }
244
        $row[] = implode(', ', $strrequired);
245
246
247
248
    } else {
        $row[] = '';
    }

249
    // Are people allowed to select this behaviour?
250
251
252
253
254
255
256
257
    $rowclass = '';
    if ($archetypal[$behaviour]) {
        $enabled = array_search($behaviour, $disabledbehaviours) === false;
        $icons = question_behaviour_enable_disable_icons($behaviour, $enabled);
        if (!$enabled) {
            $rowclass = 'dimmed_text';
        }
    } else {
258
        $icons = $OUTPUT->spacer(array('class' => 'iconsmall'));
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
    }

    // Move icons.
    $icons .= question_behaviour_icon_html('up', $behaviour, 't/up', get_string('up'), null);
    $icons .= question_behaviour_icon_html('down', $behaviour, 't/down', get_string('down'), null);
    $row[] = $icons;

    // Delete link, if available.
    if ($needed[$behaviour]) {
        $row[] = '';
    } else {
        $row[] = html_writer::link(new moodle_url($thispageurl,
                array('delete' => $behaviour, 'sesskey' => sesskey())), get_string('delete'),
                array('title' => get_string('uninstallbehaviour', 'question')));
    }

    $table->add_data($row, $rowclass);
}

$table->finish_output();

echo $OUTPUT->footer();

function question_behaviour_enable_disable_icons($behaviour, $enabled) {
    if ($enabled) {
284
        return question_behaviour_icon_html('disable', $behaviour, 't/hide',
285
286
                get_string('enabled', 'question'), get_string('disable'));
    } else {
287
        return question_behaviour_icon_html('enable', $behaviour, 't/show',
288
289
290
291
292
293
294
295
                get_string('disabled', 'question'), get_string('enable'));
    }
}

function question_behaviour_icon_html($action, $behaviour, $icon, $alt, $tip) {
    global $OUTPUT;
    return $OUTPUT->action_icon(new moodle_url('/admin/qbehaviours.php',
            array($action => $behaviour, 'sesskey' => sesskey())),
296
297
            new pix_icon($icon, $alt, 'moodle', array('title' => '', 'class' => 'iconsmall')),
            null, array('title' => $tip));
298
299
}