Proyectos de Subversion Moodle

Rev

Rev 1 | Mostrar el archivo completo | | | Autoría | Ultima modificación | Ver Log |

Rev 1 Rev 1441
Línea 22... Línea 22...
22
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
22
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 */
23
 */
Línea 24... Línea 24...
24
 
24
 
Línea 25... Línea -...
25
namespace core_courseformat\output\local\content\cm;
-
 
26
 
-
 
27
use action_menu;
25
namespace core_courseformat\output\local\content\cm;
-
 
26
 
-
 
27
use cm_info;
-
 
28
use core\context\module as context_module;
-
 
29
use core\output\action_menu;
-
 
30
use core\output\action_menu\link;
-
 
31
use core\output\action_menu\link_secondary;
28
use action_menu_link;
32
use core\output\action_menu\subpanel;
29
use cm_info;
33
use core\output\pix_icon;
30
use core\output\named_templatable;
34
use core\output\renderer_base;
-
 
35
use core_courseformat\base as course_format;
31
use core_courseformat\base as course_format;
36
use core_courseformat\output\local\content\basecontrolmenu;
32
use core_courseformat\output\local\courseformat_named_templatable;
37
use core_courseformat\sectiondelegate;
33
use renderable;
38
use core\url;
Línea 34... Línea 39...
34
use section_info;
39
use section_info;
35
use stdClass;
40
use stdClass;
36
 
41
 
37
/**
42
/**
38
 * Base class to render a course module menu inside a course format.
43
 * Base class to render a course module menu inside a course format.
39
 *
44
 *
40
 * @package   core_courseformat
45
 * @package   core_courseformat
41
 * @copyright 2020 Ferran Recio <ferran@moodle.com>
46
 * @copyright 2020 Ferran Recio <ferran@moodle.com>
Línea 42... Línea -...
42
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
-
 
43
 */
-
 
44
class controlmenu implements named_templatable, renderable {
47
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
45
 
48
 */
46
    use courseformat_named_templatable;
-
 
47
 
-
 
48
    /** @var course_format the course format */
-
 
Línea 49... Línea 49...
49
    protected $format;
49
class controlmenu extends basecontrolmenu {
50
 
50
 
Línea 51... Línea 51...
51
    /** @var section_info the section object */
51
    /** @var array optional display options */
52
    private $section;
52
    protected $displayoptions;
Línea 53... Línea 53...
53
 
53
 
54
    /** @var action_menu the activity aciton menu */
54
    /** @var context_module|null modcontext the module context if any */
Línea 55... Línea 55...
55
    protected $menu;
55
    protected ?context_module $modcontext = null;
56
 
56
 
57
    /** @var cm_info the course module instance */
57
    /** @var bool $canmanageactivities Optimization to know if the user can manage activities */
58
    protected $mod;
58
    protected bool $canmanageactivities;
59
 
59
 
60
    /** @var array optional display options */
60
    /** @var url $basemodurl the base mod.php url */
61
    protected $displayoptions;
61
    protected url $basemodurl;
62
 
62
 
63
    /**
63
    /**
64
     * Constructor.
-
 
65
     *
64
     * Constructor.
66
     * @param course_format $format the course format
-
 
67
     * @param section_info $section the section info
65
     *
-
 
66
     * @param course_format $format the course format
-
 
67
     * @param section_info $section the section info
-
 
68
     * @param cm_info $mod the course module info
-
 
69
     * @param array $displayoptions optional extra display options
-
 
70
     */
-
 
71
    public function __construct(course_format $format, section_info $section, cm_info $mod, array $displayoptions = []) {
-
 
72
        parent::__construct($format, $section, $mod, $mod->id);
-
 
73
        $this->displayoptions = $displayoptions;
-
 
74
 
68
     * @param cm_info $mod the course module info
75
        $this->modcontext = context_module::instance($mod->id);
Línea 69... Línea 76...
69
     * @param array $displayoptions optional extra display options
76
        $this->canmanageactivities = has_capability('moodle/course:manageactivities', $this->modcontext);
70
     */
77
 
71
    public function __construct(course_format $format, section_info $section, cm_info $mod, array $displayoptions = []) {
78
        $this->basemodurl = new url('/course/mod.php');
72
        $this->format = $format;
79
        $sectionnumreturn = $format->get_sectionnum();
73
        $this->section = $section;
80
        if ($sectionnumreturn !== null) {
74
        $this->mod = $mod;
81
            $this->basemodurl->param('sr', $sectionnumreturn);
75
        $this->displayoptions = $displayoptions;
82
        }
Línea 76... Línea 83...
76
    }
83
    }
Línea -... Línea 84...
-
 
84
 
-
 
85
    /**
-
 
86
     * Export this data so it can be used as the context for a mustache template.
-
 
87
     *
77
 
88
     * @param renderer_base $output typically, the renderer that's calling this function
Línea 78... Línea 89...
78
    /**
89
     * @return stdClass|null data context for a mustache template
79
     * Export this data so it can be used as the context for a mustache template.
90
     */
80
     *
91
    public function export_for_template(renderer_base $output): ?stdClass {
Línea 81... Línea 92...
81
     * @param \renderer_base $output typically, the renderer that's calling this function
92
 
82
     * @return stdClass data context for a mustache template
93
        $mod = $this->mod;
83
     */
94
 
84
    public function export_for_template(\renderer_base $output): stdClass {
95
        if (!$this->format->show_activity_editor_options($this->mod)) {
85
 
96
            return null;
Línea 86... Línea 97...
86
        $mod = $this->mod;
97
        }
87
 
98
 
88
        $menu = $this->get_action_menu($output);
99
        $menu = $this->get_action_menu($output);
Línea 107... Línea 118...
107
 
118
 
108
    /**
119
    /**
109
     * Generate the action menu element.
120
     * Generate the action menu element.
110
     *
121
     *
111
     * This method is public in case some block needs to modify the menu before output it.
122
     * This method is public in case some block needs to modify the menu before output it.
112
     * @param \renderer_base $output typically, the renderer that's calling this function
123
     * @param renderer_base $output typically, the renderer that's calling this function
113
     * @return action_menu|null the activity action menu
124
     * @return action_menu|null the activity action menu
114
     */
125
     */
Línea 115... Línea 126...
115
    public function get_action_menu(\renderer_base $output): ?action_menu {
126
    public function get_action_menu(renderer_base $output): ?action_menu {
116
 
127
 
117
        if (!empty($this->menu)) {
128
        if (!empty($this->menu)) {
Línea -... Línea 129...
-
 
129
            return $this->menu;
-
 
130
        }
-
 
131
 
-
 
132
        // In case module is delegating a section, we should return delegated section action menu.
-
 
133
        if ($delegated = $this->mod->get_delegated_section_info()) {
-
 
134
            $controlmenuclass = $this->format->get_output_classname('content\\cm\\delegatedcontrolmenu');
-
 
135
            $controlmenu = new $controlmenuclass($this->format, $delegated, $this->mod);
-
 
136
            return $controlmenu->get_action_menu($output);
-
 
137
        }
-
 
138
 
-
 
139
        // TODO remove this if as part of MDL-83530.
-
 
140
        if (!$this->format->supports_components()) {
-
 
141
            $this->menu = $this->get_action_menu_legacy($output);
-
 
142
            return $this->menu;
-
 
143
        }
-
 
144
 
-
 
145
        $controls = $this->get_cm_control_items();
-
 
146
        return $this->format_controls($controls);
-
 
147
    }
-
 
148
 
-
 
149
    /**
-
 
150
     * Generate the edit control items of a course module.
-
 
151
     *
-
 
152
     * This method uses course_get_cm_edit_actions function to get the cm actions.
-
 
153
     * However, format plugins can override the method to add or remove elements
-
 
154
     * from the menu.
-
 
155
     *
-
 
156
     * @return array of edit control items
-
 
157
     */
-
 
158
    public function get_cm_control_items(): ?array {
-
 
159
        $controls = [];
-
 
160
 
-
 
161
        $controls['update'] = $this->get_cm_edit_item();
-
 
162
        $controls['move'] = $this->get_cm_move_item();
-
 
163
        $controls['moveright'] = $this->get_cm_moveend_item();
-
 
164
        $controls['moveleft'] = $this->get_cm_movestart_item();
-
 
165
        $controls['availability'] = $this->get_cm_visibility_item();
-
 
166
        $controls['duplicate'] = $this->get_cm_duplicate_item();
-
 
167
        $controls['assign'] = $this->get_cm_assign_item();
-
 
168
        $controls['groupmode'] = $this->get_cm_groupmode_item();
-
 
169
        $controls['delete'] = $this->get_cm_delete_item();
-
 
170
 
-
 
171
        return $controls;
-
 
172
    }
-
 
173
 
-
 
174
    /**
-
 
175
     * Generates the edit settings item for a course module.
-
 
176
     *
-
 
177
     * @return link|null The menu item if applicable, otherwise null.
-
 
178
     */
-
 
179
    protected function get_cm_edit_item(): ?link {
-
 
180
        if (!$this->canmanageactivities) {
-
 
181
            return null;
-
 
182
        }
-
 
183
 
-
 
184
        $url = new url($this->basemodurl, ['update' => $this->mod->id]);
-
 
185
 
-
 
186
        return new link_secondary(
-
 
187
            url: $url,
-
 
188
            icon: new pix_icon('i/settings', ''),
-
 
189
            text: get_string('editsettings'),
-
 
190
            attributes: [
-
 
191
                'class' => 'editing_update',
-
 
192
            ],
-
 
193
        );
-
 
194
    }
-
 
195
 
-
 
196
    /**
-
 
197
     * Generates the move item for a course module.
-
 
198
     *
-
 
199
     * @return link|null The menu item if applicable, otherwise null.
-
 
200
     */
-
 
201
    protected function get_cm_move_item(): ?link {
-
 
202
        // Only show the move link if we are not already in the section view page.
-
 
203
        if (!$this->canmanageactivities) {
-
 
204
            return null;
-
 
205
        }
-
 
206
 
-
 
207
        $url = new url($this->basemodurl);
-
 
208
 
-
 
209
        return new link_secondary(
-
 
210
            url: $url,
-
 
211
            icon: new pix_icon('i/dragdrop', ''),
-
 
212
            text: get_string('move'),
-
 
213
            attributes: [
-
 
214
                // This tool requires ajax and will appear only when the frontend state is ready.
-
 
215
                'class' => 'editing_movecm waitstate',
-
 
216
                'data-action' => 'moveCm',
-
 
217
                'data-id' => $this->mod->id,
-
 
218
            ],
-
 
219
        );
-
 
220
    }
-
 
221
 
-
 
222
    /**
-
 
223
     * Check if the course module can be indented.
-
 
224
     *
-
 
225
     * @return bool
-
 
226
     */
-
 
227
    protected function can_indent_cm(): bool {
-
 
228
        return $this->canmanageactivities
-
 
229
            && !sectiondelegate::has_delegate_class('mod_'.$this->mod->modname)
-
 
230
            && empty($this->displayoptions['disableindentation'])
-
 
231
            && $this->format->uses_indentation();
-
 
232
    }
-
 
233
 
-
 
234
    /**
-
 
235
     * Generates the move right item for a course module.
-
 
236
     *
-
 
237
     * @return link|null The menu item if applicable, otherwise null.
-
 
238
     */
-
 
239
    protected function get_cm_moveend_item(): ?link {
-
 
240
        if (!$this->can_indent_cm() || $this->mod->indent > 0) {
-
 
241
            return null;
-
 
242
        }
-
 
243
 
-
 
244
        $url = $this->format->get_update_url(
-
 
245
            action: 'cm_moveright',
-
 
246
            ids: [$this->mod->id],
-
 
247
            returnurl: $this->baseurl,
-
 
248
        );
-
 
249
 
-
 
250
        $icon = (right_to_left()) ? 't/left' : 't/right';
-
 
251
 
-
 
252
        return new link_secondary(
-
 
253
            url: $url,
-
 
254
            icon: new pix_icon($icon, ''),
-
 
255
            text: get_string('moveright'),
-
 
256
            attributes: [
-
 
257
                'class' => 'editing_moveright',
-
 
258
                'data-action' => 'cmMoveRight',
-
 
259
                'data-keepopen' => true,
-
 
260
                'data-sectionreturn' => $this->format->get_sectionnum(),
-
 
261
                'data-id' => $this->mod->id,
-
 
262
            ],
-
 
263
        );
-
 
264
    }
-
 
265
 
-
 
266
    /**
-
 
267
     * Generates the move left item for a course module.
-
 
268
     *
-
 
269
     * @return link|null The menu item if applicable, otherwise null.
-
 
270
     */
-
 
271
    protected function get_cm_movestart_item(): ?link {
-
 
272
        if (!$this->can_indent_cm() || $this->mod->indent <= 0) {
-
 
273
            return null;
-
 
274
        }
-
 
275
 
-
 
276
        $url = $this->format->get_update_url(
-
 
277
            action: 'cm_moveleft',
-
 
278
            ids: [$this->mod->id],
-
 
279
            returnurl: $this->baseurl,
-
 
280
        );
-
 
281
 
-
 
282
        $icon = (right_to_left()) ? 't/right' : 't/left';
-
 
283
 
-
 
284
        return new link_secondary(
-
 
285
            url: $url,
-
 
286
            icon: new pix_icon($icon, ''),
-
 
287
            text: get_string('moveleft'),
-
 
288
            attributes: [
-
 
289
                'class' => 'editing_moveleft',
-
 
290
                'data-action' => 'cmMoveLeft',
-
 
291
                'data-keepopen' => true,
-
 
292
                'data-sectionreturn' => $this->format->get_sectionnum(),
-
 
293
                'data-id' => $this->mod->id,
-
 
294
            ],
-
 
295
        );
-
 
296
    }
-
 
297
 
-
 
298
    /**
-
 
299
     * Generates the visibility item for a course module.
-
 
300
     *
-
 
301
     * @return link|null The menu item if applicable, otherwise null.
-
 
302
     */
-
 
303
    protected function get_cm_visibility_item(): link_secondary|subpanel|null {
-
 
304
        if (!has_capability('moodle/course:activityvisibility', $this->modcontext)) {
-
 
305
            return null;
-
 
306
        }
-
 
307
        $outputclass = $this->format->get_output_classname('content\\cm\\visibility');
-
 
308
        /** @var \core_courseformat\output\local\content\cm\visibility $output */
-
 
309
        $output = new $outputclass($this->format, $this->section, $this->mod);
-
 
310
        return $output->get_menu_item();
-
 
311
    }
-
 
312
 
-
 
313
    /**
-
 
314
     * Generates the duplicate item for a course module.
-
 
315
     *
-
 
316
     * @return link|null The menu item if applicable, otherwise null.
-
 
317
     */
-
 
318
    protected function get_cm_duplicate_item(): ?link {
-
 
319
        if (
-
 
320
            !has_all_capabilities(
-
 
321
                ['moodle/backup:backuptargetimport', 'moodle/restore:restoretargetimport'],
-
 
322
                $this->coursecontext
-
 
323
            )
-
 
324
            || !plugin_supports('mod', $this->mod->modname, FEATURE_BACKUP_MOODLE2)
-
 
325
            || !course_allowed_module($this->mod->get_course(), $this->mod->modname)
-
 
326
        ) {
-
 
327
                return null;
-
 
328
        }
-
 
329
 
-
 
330
        $url = $this->format->get_update_url(
-
 
331
            action: 'cm_duplicate',
-
 
332
            ids: [$this->mod->id],
-
 
333
            returnurl: $this->baseurl,
-
 
334
        );
-
 
335
 
-
 
336
        return new link_secondary(
-
 
337
            url: $url,
-
 
338
            icon: new pix_icon('t/copy', ''),
-
 
339
            text: get_string('duplicate'),
-
 
340
            attributes: [
-
 
341
                'class' => 'editing_duplicate',
-
 
342
                'data-action' => 'cmDuplicate',
-
 
343
                'data-sectionreturn' => $this->format->get_sectionnum(),
-
 
344
                'data-id' => $this->mod->id,
-
 
345
            ],
-
 
346
        );
-
 
347
    }
-
 
348
 
-
 
349
    /**
-
 
350
     * Generates the assign roles item for a course module.
-
 
351
     *
-
 
352
     * @return link|null The menu item if applicable, otherwise null.
-
 
353
     */
-
 
354
    protected function get_cm_assign_item(): ?link {
-
 
355
        if (
-
 
356
            !has_capability('moodle/role:assign', $this->modcontext)
-
 
357
            || sectiondelegate::has_delegate_class('mod_'.$this->mod->modname)
-
 
358
        ) {
-
 
359
            return null;
-
 
360
        }
-
 
361
 
-
 
362
        return new link_secondary(
-
 
363
            url: new url('/admin/roles/assign.php', ['contextid' => $this->modcontext->id]),
-
 
364
            icon: new pix_icon('t/assignroles', ''),
-
 
365
            text: get_string('assignroles', 'role'),
-
 
366
            attributes: [
-
 
367
                'class' => 'editing_assign',
-
 
368
                'data-sectionreturn' => $this->format->get_sectionnum(),
-
 
369
            ],
-
 
370
        );
-
 
371
    }
-
 
372
 
-
 
373
    /**
-
 
374
     * Generates the group mode item for a course module.
-
 
375
     *
-
 
376
     * @return subpanel|null The menu item if applicable, otherwise null.
-
 
377
     */
-
 
378
    protected function get_cm_groupmode_item(): ?subpanel {
-
 
379
        if (
-
 
380
            !$this->format->show_groupmode($this->mod)
-
 
381
            || $this->mod->coursegroupmodeforce
-
 
382
        ) {
-
 
383
            return null;
-
 
384
        }
-
 
385
 
-
 
386
        $groupmodeclass = $this->format->get_output_classname('content\\cm\\groupmode');
-
 
387
        /** @var \core_courseformat\output\local\content\cm\groupmode $groupmode */
-
 
388
        $groupmode = new $groupmodeclass($this->format, $this->section, $this->mod);
-
 
389
        return new subpanel(
-
 
390
            text: get_string('groupmode', 'group'),
-
 
391
            subpanel: $groupmode->get_choice_list(),
-
 
392
            attributes: ['class' => 'editing_groupmode'],
-
 
393
            icon: new pix_icon('t/groupv', '', 'moodle', ['class' => 'iconsmall']),
-
 
394
        );
-
 
395
    }
-
 
396
 
-
 
397
    /**
-
 
398
     * Generates the delete item for a course module.
-
 
399
     *
-
 
400
     * @return link|null The menu item if applicable, otherwise null.
-
 
401
     */
-
 
402
    protected function get_cm_delete_item(): ?link {
-
 
403
        if (!$this->canmanageactivities) {
-
 
404
            return null;
-
 
405
        }
-
 
406
 
-
 
407
        $url = $this->format->get_update_url(
-
 
408
            action: 'cm_delete',
-
 
409
            ids: [$this->mod->id],
-
 
410
            returnurl: $this->baseurl,
-
 
411
        );
-
 
412
 
-
 
413
        return new link_secondary(
-
 
414
            url: $url,
-
 
415
            icon: new pix_icon('t/delete', ''),
-
 
416
            text: get_string('delete'),
-
 
417
            attributes: [
-
 
418
                'class' => 'editing_delete text-danger',
-
 
419
                'data-action' => 'cmDelete',
-
 
420
                'data-sectionreturn' => $this->format->get_sectionnum(),
-
 
421
                'data-id' => $this->mod->id,
-
 
422
            ],
-
 
423
        );
-
 
424
    }
-
 
425
 
-
 
426
    /**
-
 
427
     * Generate the action menu element for old course formats.
-
 
428
     *
-
 
429
     * This method is public in case some block needs to modify the menu before output it.
-
 
430
     *
-
 
431
     * @todo Remove this method in Moodle 6.0 (MDL-83530).
-
 
432
     * @param \renderer_base $output typically, the renderer that's calling this function
118
            return $this->menu;
433
     * @return action_menu|null the activity action menu
Línea 119... Línea 434...
119
        }
434
     */
Línea 120... Línea 435...
120
 
435
    private function get_action_menu_legacy(\renderer_base $output): ?action_menu {
Línea 136... Línea 451...
136
 
451
 
137
        $ownerselector = $this->displayoptions['ownerselector'] ?? '#module-' . $mod->id;
452
        $ownerselector = $this->displayoptions['ownerselector'] ?? '#module-' . $mod->id;
Línea 138... Línea 453...
138
        $menu->set_owner_selector($ownerselector);
453
        $menu->set_owner_selector($ownerselector);
139
 
454
 
140
        foreach ($controls as $control) {
455
        foreach ($controls as $control) {
141
            if ($control instanceof action_menu_link) {
456
            if ($control instanceof link) {
142
                $control->add_class('cm-edit-action');
457
                $control->add_class('cm-edit-action');
143
            }
458
            }
Línea 154... Línea 469...
154
     *
469
     *
155
     * This method uses course_get_cm_edit_actions function to get the cm actions.
470
     * This method uses course_get_cm_edit_actions function to get the cm actions.
156
     * However, format plugins can override the method to add or remove elements
471
     * However, format plugins can override the method to add or remove elements
157
     * from the menu.
472
     * from the menu.
158
     *
473
     *
-
 
474
     * @deprecated since Moodle 5.0
-
 
475
     * @todo Remove this method in Moodle 6.0 (MDL-83530).
159
     * @return array of edit control items
476
     * @return array of edit control items
160
     */
477
     */
-
 
478
    #[\core\attribute\deprecated(
-
 
479
        replacement: 'get_cm_control_items',
-
 
480
        since: '5.0',
-
 
481
        mdl: 'MDL-83527',
-
 
482
    )]
161
    protected function cm_control_items() {
483
    protected function cm_control_items() {
-
 
484
        \core\deprecation::emit_deprecation([self::class, __FUNCTION__]);
162
        $format = $this->format;
485
        $format = $this->format;
163
        $mod = $this->mod;
486
        $mod = $this->mod;
164
        $sectionreturn = $format->get_sectionnum();
487
        $sectionreturn = $format->get_sectionnum();
165
        if (!empty($this->displayoptions['disableindentation']) || !$format->uses_indentation()) {
488
        if (!empty($this->displayoptions['disableindentation']) || !$format->uses_indentation()) {
166
            $indent = -1;
489
            $indent = -1;