Proyectos de Subversion Moodle

Rev

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