Proyectos de Subversion Moodle

Rev

Rev 1 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
// This file is part of Moodle - http://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
namespace qbank_columnsortorder;
18
 
19
defined('MOODLE_INTERNAL') || die();
20
 
21
require_once($CFG->libdir . '/questionlib.php');
22
 
23
use context_system;
24
use core_question\local\bank\column_base;
25
use core_question\local\bank\column_manager_base;
26
use core_question\local\bank\question_edit_contexts;
27
use core_question\local\bank\view;
1441 ariadna 28
use core_question\local\bank\question_bank_helper;
1 efrain 29
use qbank_columnsortorder\local\bank\column_action_move;
30
use qbank_columnsortorder\local\bank\column_action_remove;
31
use qbank_columnsortorder\local\bank\column_action_resize;
32
use qbank_columnsortorder\local\bank\preview_view;
33
use moodle_url;
34
 
35
/**
36
 * Class column_manager responsible for loading and saving order to the config setting.
37
 *
38
 * @package    qbank_columnsortorder
39
 * @copyright  2021 Catalyst IT Australia Pty Ltd
40
 * @author     Ghaly Marc-Alexandre <marc-alexandreghaly@catalyst-ca.net>
41
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
42
 */
43
class column_manager extends column_manager_base {
44
    /**
45
     * @var array Column order as set in config_plugins 'class' => 'position', ie: question_type_column => 3.
46
     */
47
    public $columnorder;
48
 
49
    /**
50
     * @var array hidden columns.
51
     */
52
    public $hiddencolumns;
53
 
54
    /**
55
     * @var array columns with size.
56
     */
57
    public $colsize;
58
 
59
    /**
60
     * @var array Disabled columns in config_plugins table.
61
     */
62
    public $disabledcolumns;
63
 
64
    /**
65
     * Constructor for column_manager class.
66
     *
67
     * @param bool $globalsettings Only use the global default settings, ignoring user preferences?
68
     */
69
    public function __construct(bool $globalsettings = false) {
70
        $this->columnorder = $this->setup_property('enabledcol', $globalsettings);
71
        if (empty($this->columnorder)) {
72
            $this->columnorder = [
73
                'core_question\local\bank\checkbox_column' . column_base::ID_SEPARATOR . 'checkbox_column',
74
                'qbank_viewquestiontype\question_type_column' . column_base::ID_SEPARATOR . 'question_type_column',
75
                'qbank_viewquestionname\question_name_idnumber_tags_column' . column_base::ID_SEPARATOR .
76
                'question_name_idnumber_tags_column',
77
                    'core_question\local\bank\edit_menu_column' . column_base::ID_SEPARATOR . 'edit_menu_column',
78
                'qbank_editquestion\question_status_column' . column_base::ID_SEPARATOR . 'question_status_column',
79
                'qbank_history\version_number_column' . column_base::ID_SEPARATOR . 'version_number_column',
80
                'qbank_viewcreator\creator_name_column' . column_base::ID_SEPARATOR . 'creator_name_column',
81
                'qbank_comment\comment_count_column' . column_base::ID_SEPARATOR . 'comment_count_column',
82
            ];
83
        }
84
        $this->hiddencolumns = $this->setup_property('hiddencols', $globalsettings);
85
        $this->colsize = $this->setup_property('colsize', $globalsettings, 'json');
86
        $this->disabledcolumns = $this->setup_property('disabledcol', true); // No user preference for disabledcol.
87
 
88
        if ($this->columnorder) {
89
            $this->columnorder = array_flip($this->columnorder);
90
        }
91
        if ($this->disabledcolumns) {
92
            $this->disabledcolumns = array_flip($this->disabledcolumns);
93
        }
94
    }
95
 
96
    /**
97
     * Return the value for the given property, based the saved user preference or config setting.
98
     *
99
     * If no value is currently stored, returns an empty array.
100
     *
101
     * @param string $setting The identifier used for the saved config and user preference settings.
102
     * @param bool $global Only get the global default, ignoring the user preference?
103
     * @param string $encoding The encoding used to store the property - csv or json
104
     * @return array
105
     */
106
    private function setup_property(string $setting, bool $global = false, $encoding = 'csv'): array {
107
        $value = get_config('qbank_columnsortorder', $setting);
108
        if (!$global) {
109
            $value = get_user_preferences("qbank_columnsortorder_{$setting}", $value);
110
        }
111
        if (empty($value)) {
112
            return [];
113
        }
114
        return $encoding == 'csv' ? explode(',', $value) : json_decode($value);
115
    }
116
 
117
    /**
118
     * Sets column order in the qbank_columnsortorder plugin config.
119
     *
120
     * @param ?array $columns Column order to set. Null value clears the setting.
121
     * @param bool $global save this as a global default, rather than a user preference?
122
     */
123
    public static function set_column_order(?array $columns, bool $global = false): void {
124
        if (!is_null($columns)) {
125
            $columns = implode(',', $columns);
126
        }
127
        self::save_preference('enabledcol', $columns, $global);
128
    }
129
 
130
    /**
131
     * Hidden Columns.
132
     *
133
     * @param ?array $columns List of hidden columns. Null value clears the setting.
134
     * @param bool $global save this as a global default, rather than a user preference?
135
     */
136
    public static function set_hidden_columns(?array $columns, bool $global = false): void {
137
        if (!is_null($columns)) {
138
            $columns = implode(',', $columns);
139
        }
140
        self::save_preference('hiddencols', $columns, $global);
141
    }
142
 
143
    /**
144
     * Column size.
145
     *
146
     * @param ?string $sizes columns with width. Null value clears the setting.
147
     * @param bool $global save this as a global default, rather than a user preference?
148
     */
149
    public static function set_column_size(?string $sizes, bool $global = false): void {
150
        self::save_preference('colsize', $sizes, $global);
151
    }
152
 
153
    /**
154
     * Save Preferences.
155
     *
156
     * @param string $name name of a configuration
157
     * @param ?string $value value of a configuration. Null value clears the setting.
158
     * @param bool $global save this as a global default, rather than a user preference?
159
     */
160
    private static function save_preference(string $name, ?string $value, bool $global = false): void {
161
        if ($global) {
162
            require_capability('moodle/site:config', context_system::instance());
163
            set_config($name, $value, 'qbank_columnsortorder');
164
        } else {
165
            set_user_preference("qbank_columnsortorder_{$name}", $value);
166
        }
167
    }
168
 
169
    /**
170
     * Get qbank.
171
     *
172
     * @return view
173
     */
174
    public function get_questionbank(): view {
175
        $course = (object) ['id' => 0];
1441 ariadna 176
        $previewbank = question_bank_helper::get_preview_open_instance_type(true);
177
        $cm = $previewbank->get_course_module_record();
178
        $context = \context_module::instance($previewbank->id);
1 efrain 179
        $contexts = new question_edit_contexts($context);
1441 ariadna 180
        $category = question_get_default_category($contexts->lowest()->id, true);
1 efrain 181
        $params = ['cat' => $category->id . ',' . $context->id];
182
        // Dummy call to get the objects without error.
183
        $questionbank = new preview_view(
184
            $contexts,
185
            new moodle_url('/question/bank/columnsortorder/sortcolumns.php'),
186
            $course,
1441 ariadna 187
            $cm,
1 efrain 188
            $params
189
        );
190
        return $questionbank;
191
    }
192
 
193
    /**
194
     * Get enabled columns.
195
     *
196
     * @return array
197
     */
198
    public function get_columns(): array {
199
        $columns = [];
200
        foreach ($this->get_questionbank()->get_visiblecolumns() as $key => $column) {
201
            if ($column->get_name() === 'checkbox') {
202
                continue;
203
            }
204
            $columns[] = (object) [
205
                'class' => get_class($column),
206
                'name' => $column->get_title(),
207
                'colname' => $column->get_column_name(),
208
                'id' => $column->get_column_id(),
209
            ];
210
        }
211
        return $columns;
212
    }
213
 
214
    /**
215
     * Get disabled columns.
216
     *
217
     * @return array
218
     */
219
    public function get_disabled_columns(): array {
220
        $result = $this->create_column_objects(array_keys($this->disabledcolumns));
221
        $disabled = [];
222
        foreach ($result as $column => $columnobject) {
223
            $disabled[$column] = (object) [
224
                'disabledname' => $columnobject->get_title(),
225
            ];
226
        }
227
        return $disabled;
228
    }
229
 
230
    /**
231
     * Updates enabled and disabled config for 'qbank_columnsortorder' plugin.
232
     *
233
     * @param array $enabledcolumns Enabled columns to set.
234
     * @param array $disabledcolumns Disabled columns to set.
235
     */
236
    protected function update_config($enabledcolumns, $disabledcolumns): void {
237
        if (!empty($enabledcolumns)) {
238
            $configenabled = implode(',', array_flip($enabledcolumns));
239
            set_config('enabledcol', $configenabled, 'qbank_columnsortorder');
240
        }
241
        if (!empty($disabledcolumns)) {
242
            $configdisabled = implode(',', array_flip($disabledcolumns));
243
            set_config('disabledcol', $configdisabled, 'qbank_columnsortorder');
244
        } else {
245
            set_config('disabledcol', null, 'qbank_columnsortorder');
246
        }
247
    }
248
 
249
    /**
250
     * Enables columns.
251
     *
252
     * @param string $plugin Plugin type and name ie: qbank_viewcreator.
253
     */
254
    public function enable_columns(string $plugin): void {
255
        $enabledcolumns = [];
256
        $disabledcolumns = [];
257
        if ($this->columnorder) {
258
            $enabledcolumns = $this->columnorder;
259
        }
260
        if ($this->disabledcolumns) {
261
            $disabledcolumns = $this->disabledcolumns;
262
            foreach ($disabledcolumns as $class => $column) {
263
                if (strpos($class, $plugin) !== false) {
264
                    $enabledcolumns[$class] = $class;
265
                    if (isset($disabledcolumns[$class])) {
266
                        unset($disabledcolumns[$class]);
267
                    }
268
                }
269
            }
270
        }
271
        $this->update_config($enabledcolumns, $disabledcolumns);
272
    }
273
 
274
    /**
275
     * Disables columns.
276
     *
277
     * @param string $plugin Plugin type and name ie: qbank_viewcreator.
278
     */
279
    public function disable_columns(string $plugin): void {
280
        $disabledcolumns = [];
281
        $enabledcolumns = [];
282
        $allcolumns = $this->get_columns();
283
        if ($this->disabledcolumns) {
284
            $disabledcolumns = $this->disabledcolumns;
285
        }
286
        if ($this->columnorder) {
287
            $enabledcolumns = $this->columnorder;
288
        }
289
 
290
        foreach ($allcolumns as $column) {
291
            if (str_contains($column->class, $plugin)) {
292
                $disabledcolumns[$column->id] = $column->id;
293
                if (isset($enabledcolumns[$column->id])) {
294
                    unset($enabledcolumns[$column->id]);
295
                }
296
            }
297
        }
298
        $this->update_config($enabledcolumns, $disabledcolumns);
299
    }
300
 
301
    /**
302
     * Orders columns in the question bank view according to config_plugins table 'qbank_columnsortorder' config.
303
     *
304
     * @param array $ordertosort Unordered array of columns, [columnname => class]
305
     * @return array $properorder|$ordertosort Returns array ordered if 'qbank_columnsortorder' config exists.
306
     */
307
    public function get_sorted_columns($ordertosort): array {
308
        // Check if db has order set.
309
        if (!empty($this->columnorder)) {
310
            // Merge new order with old one.
311
            $columnsortorder = $this->columnorder;
312
            asort($columnsortorder);
313
            $columnorder = [];
314
            foreach ($columnsortorder as $columnid => $colposition) {
315
                if (array_key_exists($columnid, $ordertosort)) {
316
                    $columnorder[$columnid] = $colposition;
317
                }
318
            }
319
            $properorder = array_merge($columnorder, $ordertosort);
320
            // Always have the checkbox at first column position.
321
            $checkboxid = 'core_question\local\bank\checkbox_column' . column_base::ID_SEPARATOR . 'checkbox_column';
322
            if (isset($properorder[$checkboxid])) {
323
                $checkboxfirstelement = $properorder[$checkboxid];
324
                unset($properorder[$checkboxid]);
325
                $properorder = array_merge([
326
                        $checkboxid => $checkboxfirstelement
327
                ], $properorder);
328
            }
329
            return $properorder;
330
        }
331
        return $ordertosort;
332
    }
333
 
334
    /**
335
     * Given an array of columns, set the isvisible attribute according to $this->hiddencolumns and $this->disabledcolumns.
336
     *
337
     * @param column_base[] $columns
338
     * @return array
339
     */
340
    public function set_columns_visibility(array $columns): array {
341
        foreach ($columns as $column) {
342
            if (!is_object($column)) {
343
                continue;
344
            }
345
            $columnid = $column->get_column_id();
346
 
347
            $column->isvisible = !in_array($columnid, $this->hiddencolumns) && !array_key_exists($columnid, $this->disabledcolumns);
348
        }
349
        return $columns;
350
    }
351
 
352
    /**
353
     * Return $this->colsize mapped as an array of column name => width, excluding empty sizes.
354
     *
355
     * @return array
356
     */
357
    public function get_colsize_map(): array {
358
        $sizes = array_reduce($this->colsize, function($result, $colsize) {
359
            $result[$colsize->column] = $colsize->width;
360
            return $result;
361
        }, []);
362
        return array_filter($sizes);
363
    }
364
 
365
    /**
366
     * Return an array of hidden columns as an array of class => column name
367
     *
368
     * @return array
369
     */
370
    public function get_hidden_columns(): array {
371
        $result = $this->create_column_objects($this->hiddencolumns);
372
        $hidden = [];
373
        foreach ($result as $column => $columnobject) {
374
            $hidden[$column] = $columnobject->get_title();
375
        }
376
        return $hidden;
377
    }
378
 
379
    /**
380
     * Returns an array of column objects.
381
     *
382
     * @param array $columnsnames Array of columns.
383
     * @return column_base[] Array of $columnsname => $columnobject
384
     */
385
    public function create_column_objects(array $columnsnames): array {
386
        $result = [];
387
        foreach ($columnsnames as $column) {
388
            [$columnclass, $columnname] = explode(column_base::ID_SEPARATOR, $column, 2);
389
            if (class_exists($columnclass)) {
390
                $columnobject = $columnclass::from_column_name($this->get_questionbank(), $columnname, true);
391
                if ($columnobject != null) {
392
                    $result[$column] = $columnobject;
393
                }
394
            }
395
        }
396
        return $result;
397
    }
398
 
399
    public function get_column_width(column_base $column): string {
400
        $colsizemap = $this->get_colsize_map();
401
        $columnid = $column->get_column_id();
402
        if (array_key_exists($columnid, $colsizemap)) {
403
            return $colsizemap[$columnid] . 'px';
404
        }
405
        return parent::get_column_width($column);
406
    }
407
 
408
    public function get_column_actions(view $qbank): array {
409
        return [
410
            new column_action_move($qbank),
411
            new column_action_remove($qbank),
412
            new column_action_resize($qbank),
413
        ];
414
    }
415
}