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 activity list from a section.
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;
26
 
27
use cm_info;
28
use context_course;
29
use core\output\named_templatable;
30
use core_availability\info_module;
31
use core_courseformat\base as course_format;
32
use core_courseformat\output\local\courseformat_named_templatable;
33
use renderable;
34
use renderer_base;
35
use section_info;
36
use stdClass;
37
 
38
/**
39
 * Base class to render a course module inside a course format.
40
 *
41
 * @package   core_courseformat
42
 * @copyright 2020 Ferran Recio <ferran@moodle.com>
43
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
44
 */
45
class cm implements named_templatable, renderable {
46
    use courseformat_named_templatable;
47
 
48
    /** @var course_format the course format */
49
    protected $format;
50
 
51
    /** @var section_info the section object */
1441 ariadna 52
    protected $section;
1 efrain 53
 
54
    /** @var cm_info the course module instance */
55
    protected $mod;
56
 
57
    /** @var array optional display options */
58
    protected $displayoptions;
59
 
60
    /** @var string the activity name output class name */
61
    protected $cmnameclass;
62
 
63
    /** @var string the activity control menu class name */
64
    protected $controlmenuclass;
65
 
66
    /** @var string the activity availability class name */
67
    protected $availabilityclass;
68
 
69
    /** @var string the activity completion class name */
70
    protected $completionclass;
71
 
72
    /** @var string the activity visibility class name */
73
    protected $visibilityclass;
74
 
75
    /** @var string the activity groupmode badge class name */
76
    protected $groupmodeclass;
77
 
78
    /**
79
     * Constructor.
80
     *
81
     * @param course_format $format the course format
82
     * @param section_info $section the section info
83
     * @param cm_info $mod the course module ionfo
84
     * @param array $displayoptions optional extra display options
85
     */
86
    public function __construct(course_format $format, section_info $section, cm_info $mod, array $displayoptions = []) {
87
        $this->format = $format;
88
        $this->section = $section;
89
        $this->mod = $mod;
90
 
91
        // Add extra display options.
92
        $this->displayoptions = $displayoptions;
93
        $this->load_classes();
94
 
95
        // Get the necessary classes.
96
        $this->cmnameclass = $format->get_output_classname('content\\cm\\cmname');
97
        $this->controlmenuclass = $format->get_output_classname('content\\cm\\controlmenu');
98
        $this->availabilityclass = $format->get_output_classname('content\\cm\\availability');
99
        $this->completionclass = $format->get_output_classname('content\\cm\\completion');
100
        $this->visibilityclass = $format->get_output_classname('content\\cm\\visibility');
101
        $this->groupmodeclass = $format->get_output_classname('content\\cm\\groupmode');
102
    }
103
 
104
    /**
105
     * Export this data so it can be used as the context for a mustache template.
106
     *
107
     * @param renderer_base $output typically, the renderer that's calling this function
108
     * @return stdClass data context for a mustache template
109
     */
110
    public function export_for_template(renderer_base $output): stdClass {
111
        global $PAGE;
112
 
113
        $mod = $this->mod;
114
        $displayoptions = $this->displayoptions;
115
 
116
        $data = (object)[
117
            'grouping' => $mod->get_grouping_label($displayoptions['textclasses']),
118
            'modname' => get_string('pluginname', 'mod_' . $mod->modname),
119
            'url' => $mod->url,
120
            'activityname' => $mod->get_formatted_name(),
121
            'textclasses' => $displayoptions['textclasses'],
122
            'classlist' => [],
123
            'cmid' => $mod->id,
124
            'editing' => $PAGE->user_is_editing(),
125
            'sectionnum' => $this->section->section,
1441 ariadna 126
            'cmbulk' => !$mod->get_delegated_section_info(),
1 efrain 127
        ];
128
 
129
        // Add partial data segments.
130
        $haspartials = [];
131
        $haspartials['cmname'] = $this->add_cm_name_data($data, $output);
132
        $haspartials['availability'] = $this->add_availability_data($data, $output);
133
        $haspartials['alternative'] = $this->add_alternative_content_data($data, $output);
134
        $haspartials['completion'] = $this->add_completion_data($data, $output);
135
        $haspartials['dates'] = $this->add_dates_data($data, $output);
136
        $haspartials['editor'] = $this->add_editor_data($data, $output);
137
        $haspartials['groupmode'] = $this->add_groupmode_data($data, $output);
138
        $haspartials['visibility'] = $this->add_visibility_data($data, $output);
1441 ariadna 139
        $this->add_actvitychooserbutton_data($data, $output);
1 efrain 140
        $this->add_format_data($data, $haspartials, $output);
141
 
142
        // Calculated fields.
143
        if (!empty($data->url)) {
144
            $data->hasurl = true;
145
        }
146
        return $data;
147
    }
148
 
149
    /**
150
     * Add course module name attributes to the data structure.
151
     *
152
     * @param stdClass $data the current cm data reference
153
     * @param renderer_base $output typically, the renderer that's calling this function
154
     * @return bool if the cm has name data
155
     */
156
    protected function add_cm_name_data(stdClass &$data, renderer_base $output): bool {
157
        // Mod inplace name editable.
158
        $cmname = new $this->cmnameclass(
159
            $this->format,
160
            $this->section,
161
            $this->mod,
162
            null,
163
            $this->displayoptions
164
        );
165
        $data->cmname = $cmname->export_for_template($output);
166
        $data->hasname = $cmname->has_name();
167
        return $data->hasname;
168
    }
169
 
170
    /**
171
     * Add the module availability to the data structure.
172
     *
173
     * @param stdClass $data the current cm data reference
174
     * @param renderer_base $output typically, the renderer that's calling this function
175
     * @return bool if the cm has mod availability
176
     */
177
    protected function add_availability_data(stdClass &$data, renderer_base $output): bool {
178
        if (!$this->mod->visible) {
179
            $data->modavailability = null;
180
            return false;
181
        }
182
        // Mod availability output class.
183
        $availability = new $this->availabilityclass(
184
            $this->format,
185
            $this->section,
186
            $this->mod,
187
            $this->displayoptions
188
        );
189
        $modavailability = $availability->export_for_template($output);
1441 ariadna 190
        $data->modavailability = $modavailability ?? false;
1 efrain 191
        return $availability->has_availability($output);
192
    }
193
 
194
    /**
195
     * Add the alternative content to the data structure.
196
     *
197
     * @param stdClass $data the current cm data reference
198
     * @param renderer_base $output typically, the renderer that's calling this function
199
     * @return bool if the cm has alternative content
200
     */
201
    protected function add_alternative_content_data(stdClass &$data, renderer_base $output): bool {
202
        $altcontent = $this->mod->get_formatted_content(
203
            ['overflowdiv' => true, 'noclean' => true]
204
        );
205
        $data->altcontent = (empty($altcontent)) ? false : $altcontent;
206
        $data->afterlink = $this->mod->afterlink;
207
 
208
        $activitybadgedata = $this->mod->get_activitybadge($output);
209
        if (!empty($activitybadgedata)) {
210
            $data->activitybadge = $activitybadgedata;
211
        }
212
 
213
        return !empty($data->altcontent);
214
    }
215
 
216
    /**
217
     * Add activity dates information to the data structure.
218
     *
219
     * @param stdClass $data the current cm data reference
220
     * @param renderer_base $output typically, the renderer that's calling this function
221
     * @return bool the module has completion information
222
     */
223
    protected function add_dates_data(stdClass &$data, renderer_base $output): bool {
224
        global $USER;
225
        $course = $this->mod->get_course();
226
        if (!$course->showactivitydates) {
227
            return false;
228
        }
229
        $activitydates = \core\activity_dates::get_dates_for_module($this->mod, $USER->id);
230
        $templatedata = new \core_course\output\activity_dates($activitydates);
231
        $data->dates = $templatedata->export_for_template($output);
232
 
233
        return $data->dates->hasdates;
234
    }
235
 
236
    /**
237
     * Add activity completion information to the data structure.
238
     *
239
     * @param stdClass $data the current cm data reference
240
     * @param renderer_base $output typically, the renderer that's calling this function
241
     * @return bool the module has completion information
242
     */
243
    protected function add_completion_data(stdClass &$data, renderer_base $output): bool {
244
        $completion = new $this->completionclass($this->format, $this->section, $this->mod);
245
        $templatedata = $completion->export_for_template($output);
246
        if ($templatedata) {
247
            $data->completion = $templatedata;
248
            return true;
249
        }
250
        return false;
251
    }
252
 
253
    /**
254
     * Add activity information to the data structure.
255
     *
256
     * @param stdClass $data the current cm data reference
257
     * @param bool[] $haspartials the result of loading partial data elements
258
     * @param renderer_base $output typically, the renderer that's calling this function
259
     * @return bool if the cm has format data
260
     */
261
    protected function add_format_data(stdClass &$data, array $haspartials, renderer_base $output): bool {
262
        $result = false;
263
        // Legacy indentation.
264
        if (!empty($this->mod->indent) && $this->format->uses_indentation()) {
265
            $data->indent = $this->mod->indent;
266
            if ($this->mod->indent > 15) {
267
                $data->hugeindent = true;
268
                $result = true;
269
            }
270
        }
271
        // Stealth and hidden from student.
272
        if (!$this->mod->visible) {
273
            // This module is hidden but current user has capability to see it.
274
            $data->modhiddenfromstudents = true;
275
            $result = true;
276
        } else if ($this->mod->is_stealth()) {
277
            // This module is available but is normally not displayed on the course page
278
            // (this user can see it because they can manage it).
279
            $data->modstealth = true;
280
            $result = true;
281
        }
282
        // Special inline activity format.
283
        if (
284
            $this->mod->has_custom_cmlist_item() &&
285
            !$haspartials['availability'] &&
286
            !$haspartials['completion'] &&
287
            !$haspartials['dates'] &&
288
            !$haspartials['groupmode'] &&
289
            !isset($data->modhiddenfromstudents) &&
290
            !isset($data->modstealth) &&
291
            !$this->format->show_editor()
292
        ) {
293
            $data->modinline = true;
294
            $result = true;
295
        }
296
        return $result;
297
    }
298
 
299
    /**
300
     * Add course editor attributes to the data structure.
301
     *
302
     * @param stdClass $data the current cm data reference
303
     * @param renderer_base $output typically, the renderer that's calling this function
304
     * @return bool if the cm has editor data
305
     */
306
    protected function add_editor_data(stdClass &$data, renderer_base $output): bool {
307
        $course = $this->format->get_course();
308
        $coursecontext = context_course::instance($course->id);
309
        $editcaps = [];
310
        if (has_capability('moodle/course:activityvisibility', $coursecontext)) {
311
            $editcaps = ['moodle/course:activityvisibility'];
312
        }
313
        if (!$this->format->show_editor($editcaps)) {
314
            return false;
315
        }
316
        $returnsection = $this->format->get_sectionnum();
317
        // Edit actions.
318
        $controlmenu = new $this->controlmenuclass(
319
            $this->format,
320
            $this->section,
321
            $this->mod,
322
            $this->displayoptions
323
        );
1441 ariadna 324
        $data->controlmenu = $controlmenu->export_for_template($output) ?? false;
325
 
1 efrain 326
        if (!$this->format->supports_components()) {
327
            // Add the legacy YUI move link.
328
            $data->moveicon = course_get_cm_move($this->mod, $returnsection);
329
        }
330
        return true;
331
    }
332
 
333
    /**
334
     * Add group mode information to the data structure.
335
     *
336
     * @param stdClass $data the current cm data reference
337
     * @param renderer_base $output typically, the renderer that's calling this function
338
     * @return bool the module has group mode information
339
     */
340
    protected function add_groupmode_data(stdClass &$data, renderer_base $output): bool {
341
        $groupmode = new $this->groupmodeclass($this->format, $this->section, $this->mod);
342
        $data->groupmodeinfo = $groupmode->export_for_template($output);
343
        return !empty($data->groupmodeinfo);
344
    }
345
 
346
    /**
347
     * Add visibility information to the data structure.
348
     *
349
     * @param stdClass $data the current cm data reference
350
     * @param renderer_base $output typically, the renderer that's calling this function
351
     * @return bool if the cm has visibility data
352
     */
353
    protected function add_visibility_data(stdClass &$data, renderer_base $output): bool {
354
        $visibility = new $this->visibilityclass($this->format, $this->section, $this->mod);
355
        $templatedata = $visibility->export_for_template($output);
1441 ariadna 356
        $data->visibility = $templatedata ?? false;
1 efrain 357
        if ($templatedata) {
358
            return true;
359
        }
360
        return false;
361
    }
362
 
363
    /**
1441 ariadna 364
     * Add the activity chooser button data to the data structure.
365
     *
366
     * @param stdClass $data the current cm data reference
367
     * @param renderer_base $output typically, the renderer that's calling this function
368
     */
369
    protected function add_actvitychooserbutton_data(stdClass &$data, renderer_base $output): void {
370
        $activitychooserbutton = new \core_course\output\activitychooserbutton($this->section, $this->mod);
371
        $data->activitychooserbutton = $activitychooserbutton->export_for_template($output);
372
    }
373
 
374
    /**
1 efrain 375
     * Returns the CSS classes for the activity name/content
376
     *
377
     */
378
    protected function load_classes() {
379
        $mod = $this->mod;
380
 
381
        $linkclasses = '';
382
        $textclasses = '';
383
        if ($mod->uservisible) {
384
            $info = new info_module($mod);
385
            $conditionalhidden = !$info->is_available_for_all();
386
            $accessiblebutdim = (!$mod->visible || $conditionalhidden) &&
387
                has_capability('moodle/course:viewhiddenactivities', $mod->context);
388
            if ($accessiblebutdim && $conditionalhidden) {
389
                $linkclasses .= ' conditionalhidden';
390
                $textclasses .= ' conditionalhidden';
391
            }
392
        }
393
        $this->displayoptions['linkclasses'] = $linkclasses;
394
        $this->displayoptions['textclasses'] = $textclasses;
395
        $this->displayoptions['onclick'] = htmlspecialchars_decode($mod->onclick, ENT_QUOTES);;
396
    }
397
 
398
    /**
399
     * Get the activity link classes.
400
     *
401
     * @return string the activity link classes.
402
     */
403
    public function get_link_classes(): string {
404
        return $this->displayoptions['linkclasses'] ?? '';
405
    }
406
 
407
    /**
408
     * Get the activity text/description classes.
409
     *
410
     * @return string the activity text classes.
411
     */
412
    public function get_text_classes(): string {
413
        return $this->displayoptions['textclasses'] ?? '';
414
    }
415
 
416
    /**
417
     * Get the activity onclick code.
418
     *
419
     * @return string the activity onclick.
420
     */
421
    public function get_onclick_code(): string {
422
        return $this->displayoptions['onclick'];
423
    }
424
}