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
/**
18
 * Contains the default section controls output class.
19
 *
20
 * @package   core_courseformat
21
 * @copyright 2020 Ferran Recio <ferran@moodle.com>
22
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 */
24
 
25
namespace core_courseformat\output\local\content\section;
26
 
27
use action_menu;
28
use action_menu_link_secondary;
29
use context_course;
30
use core\output\named_templatable;
31
use core_courseformat\base as course_format;
32
use core_courseformat\output\local\courseformat_named_templatable;
33
use moodle_url;
34
use pix_icon;
35
use renderable;
36
use section_info;
37
use stdClass;
38
 
39
/**
40
 * Base class to render section controls.
41
 *
42
 * @package   core_courseformat
43
 * @copyright 2020 Ferran Recio <ferran@moodle.com>
44
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
45
 */
46
class controlmenu implements named_templatable, renderable {
47
 
48
    use courseformat_named_templatable;
49
 
50
    /** @var course_format the course format class */
51
    protected $format;
52
 
53
    /** @var section_info the course section class */
54
    protected $section;
55
 
56
    /**
57
     * Constructor.
58
     *
59
     * @param course_format $format the course format
60
     * @param section_info $section the section info
61
     */
62
    public function __construct(course_format $format, section_info $section) {
63
        $this->format = $format;
64
        $this->section = $section;
65
    }
66
 
67
    /**
68
     * Export this data so it can be used as the context for a mustache template.
69
     *
70
     * @param \renderer_base $output typically, the renderer that's calling this function
71
     * @return array data context for a mustache template
72
     */
73
    public function export_for_template(\renderer_base $output): stdClass {
74
        $menu = $this->get_action_menu($output);
75
        if (empty($menu)) {
76
            return new stdClass();
77
        }
78
 
79
        $data = (object)[
80
            'menu' => $output->render($menu),
81
            'hasmenu' => true,
82
            'id' => $this->section->id,
83
        ];
84
 
85
        return $data;
86
    }
87
 
88
    /**
89
     * Generate the action menu element depending on the section.
90
     *
91
     * Sections controlled by a plugin will delegate the control menu to the plugin.
92
     *
93
     * @param \renderer_base $output typically, the renderer that's calling this function
94
     * @return action_menu|null the activity action menu or null if no action menu is available
95
     */
96
    public function get_action_menu(\renderer_base $output): ?action_menu {
97
        $sectiondelegate = $this->section->get_component_instance();
98
        if ($sectiondelegate) {
99
            return $sectiondelegate->get_section_action_menu($this->format, $this, $output);
100
        }
101
        return $this->get_default_action_menu($output);
102
    }
103
 
104
    /**
105
     * Generate the default section action menu.
106
     *
107
     * This method is public in case some block needs to modify the menu before output it.
108
     *
109
     * @param \renderer_base $output typically, the renderer that's calling this function
110
     * @return action_menu|null the activity action menu
111
     */
112
    public function get_default_action_menu(\renderer_base $output): ?action_menu {
113
        $controls = $this->section_control_items();
114
        if (empty($controls)) {
115
            return null;
116
        }
117
 
118
        // Convert control array into an action_menu.
119
        $menu = new action_menu();
120
        $menu->set_kebab_trigger(get_string('edit'));
121
        $menu->attributes['class'] .= ' section-actions';
11 efrain 122
        $menu->attributes['data-sectionid'] = $this->section->id;
1 efrain 123
        foreach ($controls as $value) {
124
            $url = empty($value['url']) ? '' : $value['url'];
125
            $icon = empty($value['icon']) ? '' : $value['icon'];
126
            $name = empty($value['name']) ? '' : $value['name'];
127
            $attr = empty($value['attr']) ? [] : $value['attr'];
128
            $class = empty($value['pixattr']['class']) ? '' : $value['pixattr']['class'];
129
            $al = new action_menu_link_secondary(
130
                new moodle_url($url),
131
                new pix_icon($icon, '', null, ['class' => "smallicon " . $class]),
132
                $name,
133
                $attr
134
            );
135
            $menu->add($al);
136
        }
137
        return $menu;
138
    }
139
 
140
    /**
141
     * Generate the edit control items of a section.
142
     *
143
     * It is not clear this kind of controls are still available in 4.0 so, for now, this
144
     * method is almost a clone of the previous section_control_items from the course/renderer.php.
145
     *
146
     * This method must remain public until the final deprecation of section_edit_control_items.
147
     *
148
     * @return array of edit control items
149
     */
150
    public function section_control_items() {
151
        global $USER, $PAGE;
152
 
153
        $format = $this->format;
154
        $section = $this->section;
155
        $course = $format->get_course();
156
        $sectionreturn = !is_null($format->get_sectionid()) ? $format->get_sectionnum() : null;
157
        $user = $USER;
158
 
159
        $usecomponents = $format->supports_components();
160
        $coursecontext = context_course::instance($course->id);
161
        $numsections = $format->get_last_section_number();
162
        $isstealth = $section->section > $numsections;
163
 
164
        $baseurl = course_get_url($course, $sectionreturn);
165
        $baseurl->param('sesskey', sesskey());
166
 
167
        $controls = [];
168
 
169
        // Only show the view link if we are not already in the section view page.
170
        if ($PAGE->pagetype !== 'course-view-section-' . $course->format) {
171
            $controls['view'] = [
172
                'url'   => new moodle_url('/course/section.php', ['id' => $section->id]),
173
                'icon' => 'i/viewsection',
174
                'name' => get_string('view'),
175
                'pixattr' => ['class' => ''],
176
                'attr' => ['class' => 'icon view'],
177
            ];
178
        }
179
 
180
        if (!$isstealth && has_capability('moodle/course:update', $coursecontext, $user)) {
181
            $params = ['id' => $section->id];
182
            $params['sr'] = $section->section;
183
            if (get_string_manager()->string_exists('editsection', 'format_'.$format->get_format())) {
184
                $streditsection = get_string('editsection', 'format_'.$format->get_format());
185
            } else {
186
                $streditsection = get_string('editsection');
187
            }
188
 
189
            $controls['edit'] = [
190
                'url'   => new moodle_url('/course/editsection.php', $params),
191
                'icon' => 'i/settings',
192
                'name' => $streditsection,
193
                'pixattr' => ['class' => ''],
194
                'attr' => ['class' => 'icon edit'],
195
            ];
196
 
11 efrain 197
            if ($section->section) {
198
                $duplicatesectionurl = clone($baseurl);
199
                $duplicatesectionurl->param('sectionid', $section->id);
200
                $duplicatesectionurl->param('duplicatesection', 1);
201
                if (!is_null($sectionreturn)) {
202
                    $duplicatesectionurl->param('sr', $sectionreturn);
203
                }
204
                $controls['duplicate'] = [
205
                    'url' => $duplicatesectionurl,
206
                    'icon' => 't/copy',
207
                    'name' => get_string('duplicate'),
208
                    'pixattr' => ['class' => ''],
209
                    'attr' => ['class' => 'icon duplicate'],
210
                ];
1 efrain 211
            }
212
        }
213
 
214
        if ($section->section) {
215
            $url = clone($baseurl);
216
            if (!is_null($sectionreturn)) {
217
                $url->param('sectionid', $format->get_sectionid());
218
            }
219
            if (!$isstealth) {
220
                if (has_capability('moodle/course:sectionvisibility', $coursecontext, $user)) {
221
                    $strhidefromothers = get_string('hidefromothers', 'format_' . $course->format);
222
                    $strshowfromothers = get_string('showfromothers', 'format_' . $course->format);
223
                    if ($section->visible) { // Show the hide/show eye.
224
                        $url->param('hide', $section->section);
11 efrain 225
                        $controls['visibility'] = [
1 efrain 226
                            'url' => $url,
11 efrain 227
                            'icon' => 'i/show',
1 efrain 228
                            'name' => $strhidefromothers,
229
                            'pixattr' => ['class' => ''],
230
                            'attr' => [
231
                                'class' => 'icon editing_showhide',
232
                                'data-sectionreturn' => $sectionreturn,
233
                                'data-action' => ($usecomponents) ? 'sectionHide' : 'hide',
234
                                'data-id' => $section->id,
11 efrain 235
                                'data-icon' => 'i/show',
1 efrain 236
                                'data-swapname' => $strshowfromothers,
11 efrain 237
                                'data-swapicon' => 'i/hide',
1 efrain 238
                            ],
239
                        ];
240
                    } else {
241
                        $url->param('show',  $section->section);
11 efrain 242
                        $controls['visibility'] = [
1 efrain 243
                            'url' => $url,
11 efrain 244
                            'icon' => 'i/hide',
1 efrain 245
                            'name' => $strshowfromothers,
246
                            'pixattr' => ['class' => ''],
247
                            'attr' => [
248
                                'class' => 'icon editing_showhide',
249
                                'data-sectionreturn' => $sectionreturn,
250
                                'data-action' => ($usecomponents) ? 'sectionShow' : 'show',
251
                                'data-id' => $section->id,
11 efrain 252
                                'data-icon' => 'i/hide',
1 efrain 253
                                'data-swapname' => $strhidefromothers,
11 efrain 254
                                'data-swapicon' => 'i/show',
1 efrain 255
                            ],
256
                        ];
257
                    }
258
                }
259
 
260
                if (!$sectionreturn && has_capability('moodle/course:movesections', $coursecontext, $user)) {
261
                    if ($usecomponents) {
262
                        // This tool will appear only when the state is ready.
263
                        $url = clone ($baseurl);
264
                        $url->param('movesection', $section->section);
265
                        $url->param('section', $section->section);
266
                        $controls['movesection'] = [
267
                            'url' => $url,
268
                            'icon' => 'i/dragdrop',
269
                            'name' => get_string('move', 'moodle'),
270
                            'pixattr' => ['class' => ''],
271
                            'attr' => [
272
                                'class' => 'icon move waitstate',
273
                                'data-action' => 'moveSection',
274
                                'data-id' => $section->id,
275
                            ],
276
                        ];
277
                    }
278
                    // Legacy move up and down links for non component-based formats.
279
                    $url = clone($baseurl);
280
                    if ($section->section > 1) { // Add a arrow to move section up.
281
                        $url->param('section', $section->section);
282
                        $url->param('move', -1);
283
                        $strmoveup = get_string('moveup');
284
                        $controls['moveup'] = [
285
                            'url' => $url,
286
                            'icon' => 'i/up',
287
                            'name' => $strmoveup,
288
                            'pixattr' => ['class' => ''],
289
                            'attr' => ['class' => 'icon moveup whilenostate'],
290
                        ];
291
                    }
292
 
293
                    $url = clone($baseurl);
294
                    if ($section->section < $numsections) { // Add a arrow to move section down.
295
                        $url->param('section', $section->section);
296
                        $url->param('move', 1);
297
                        $strmovedown = get_string('movedown');
298
                        $controls['movedown'] = [
299
                            'url' => $url,
300
                            'icon' => 'i/down',
301
                            'name' => $strmovedown,
302
                            'pixattr' => ['class' => ''],
303
                            'attr' => ['class' => 'icon movedown whilenostate'],
304
                        ];
305
                    }
306
                }
307
            }
308
 
309
            if (course_can_delete_section($course, $section)) {
310
                if (get_string_manager()->string_exists('deletesection', 'format_'.$course->format)) {
311
                    $strdelete = get_string('deletesection', 'format_'.$course->format);
312
                } else {
313
                    $strdelete = get_string('deletesection');
314
                }
315
                $params = [
316
                    'id' => $section->id,
317
                    'delete' => 1,
318
                    'sesskey' => sesskey(),
319
                ];
320
                if (!is_null($sectionreturn)) {
321
                    $params['sr'] = $sectionreturn;
322
                }
323
                $url = new moodle_url(
324
                    '/course/editsection.php',
325
                    $params,
326
                );
327
                $controls['delete'] = [
328
                    'url' => $url,
329
                    'icon' => 'i/delete',
330
                    'name' => $strdelete,
331
                    'pixattr' => ['class' => ''],
332
                    'attr' => [
333
                        'class' => 'icon editing_delete text-danger',
334
                        'data-action' => 'deleteSection',
335
                        'data-id' => $section->id,
336
                    ],
337
                ];
338
            }
339
        }
340
        if (
341
            has_any_capability([
342
                'moodle/course:movesections',
343
                'moodle/course:update',
344
                'moodle/course:sectionvisibility',
345
            ], $coursecontext)
346
        ) {
347
            $sectionlink = new moodle_url(
348
                '/course/section.php',
349
                ['id' => $section->id]
350
            );
351
            $controls['permalink'] = [
352
                'url' => $sectionlink,
353
                'icon' => 'i/link',
354
                'name' => get_string('sectionlink', 'course'),
355
                'pixattr' => ['class' => ''],
356
                'attr' => [
357
                    'class' => 'icon',
358
                    'data-action' => 'permalink',
359
                ],
360
            ];
361
        }
362
 
363
        return $controls;
364
    }
365
}