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
/**
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 */
52
    private $section;
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,
126
        ];
127
 
128
        // Add partial data segments.
129
        $haspartials = [];
130
        $haspartials['cmname'] = $this->add_cm_name_data($data, $output);
131
        $haspartials['availability'] = $this->add_availability_data($data, $output);
132
        $haspartials['alternative'] = $this->add_alternative_content_data($data, $output);
133
        $haspartials['completion'] = $this->add_completion_data($data, $output);
134
        $haspartials['dates'] = $this->add_dates_data($data, $output);
135
        $haspartials['editor'] = $this->add_editor_data($data, $output);
136
        $haspartials['groupmode'] = $this->add_groupmode_data($data, $output);
137
        $haspartials['visibility'] = $this->add_visibility_data($data, $output);
138
        $this->add_format_data($data, $haspartials, $output);
139
 
140
        // Calculated fields.
141
        if (!empty($data->url)) {
142
            $data->hasurl = true;
143
        }
144
        return $data;
145
    }
146
 
147
    /**
148
     * Add course module name attributes to the data structure.
149
     *
150
     * @param stdClass $data the current cm data reference
151
     * @param renderer_base $output typically, the renderer that's calling this function
152
     * @return bool if the cm has name data
153
     */
154
    protected function add_cm_name_data(stdClass &$data, renderer_base $output): bool {
155
        // Mod inplace name editable.
156
        $cmname = new $this->cmnameclass(
157
            $this->format,
158
            $this->section,
159
            $this->mod,
160
            null,
161
            $this->displayoptions
162
        );
163
        $data->cmname = $cmname->export_for_template($output);
164
        $data->hasname = $cmname->has_name();
165
        return $data->hasname;
166
    }
167
 
168
    /**
169
     * Add the module availability to the data structure.
170
     *
171
     * @param stdClass $data the current cm data reference
172
     * @param renderer_base $output typically, the renderer that's calling this function
173
     * @return bool if the cm has mod availability
174
     */
175
    protected function add_availability_data(stdClass &$data, renderer_base $output): bool {
176
        if (!$this->mod->visible) {
177
            $data->modavailability = null;
178
            return false;
179
        }
180
        // Mod availability output class.
181
        $availability = new $this->availabilityclass(
182
            $this->format,
183
            $this->section,
184
            $this->mod,
185
            $this->displayoptions
186
        );
187
        $modavailability = $availability->export_for_template($output);
188
        $data->modavailability = $modavailability;
189
        return $availability->has_availability($output);
190
    }
191
 
192
    /**
193
     * Add the alternative content to the data structure.
194
     *
195
     * @param stdClass $data the current cm data reference
196
     * @param renderer_base $output typically, the renderer that's calling this function
197
     * @return bool if the cm has alternative content
198
     */
199
    protected function add_alternative_content_data(stdClass &$data, renderer_base $output): bool {
200
        $altcontent = $this->mod->get_formatted_content(
201
            ['overflowdiv' => true, 'noclean' => true]
202
        );
203
        $data->altcontent = (empty($altcontent)) ? false : $altcontent;
204
        $data->afterlink = $this->mod->afterlink;
205
 
206
        $activitybadgedata = $this->mod->get_activitybadge($output);
207
        if (!empty($activitybadgedata)) {
208
            $data->activitybadge = $activitybadgedata;
209
        }
210
 
211
        return !empty($data->altcontent);
212
    }
213
 
214
    /**
215
     * Add activity dates information to the data structure.
216
     *
217
     * @param stdClass $data the current cm data reference
218
     * @param renderer_base $output typically, the renderer that's calling this function
219
     * @return bool the module has completion information
220
     */
221
    protected function add_dates_data(stdClass &$data, renderer_base $output): bool {
222
        global $USER;
223
        $course = $this->mod->get_course();
224
        if (!$course->showactivitydates) {
225
            return false;
226
        }
227
        $activitydates = \core\activity_dates::get_dates_for_module($this->mod, $USER->id);
228
        $templatedata = new \core_course\output\activity_dates($activitydates);
229
        $data->dates = $templatedata->export_for_template($output);
230
 
231
        return $data->dates->hasdates;
232
    }
233
 
234
    /**
235
     * Add activity completion information to the data structure.
236
     *
237
     * @param stdClass $data the current cm data reference
238
     * @param renderer_base $output typically, the renderer that's calling this function
239
     * @return bool the module has completion information
240
     */
241
    protected function add_completion_data(stdClass &$data, renderer_base $output): bool {
242
        $completion = new $this->completionclass($this->format, $this->section, $this->mod);
243
        $templatedata = $completion->export_for_template($output);
244
        if ($templatedata) {
245
            $data->completion = $templatedata;
246
            return true;
247
        }
248
        return false;
249
    }
250
 
251
    /**
252
     * Add activity information to the data structure.
253
     *
254
     * @param stdClass $data the current cm data reference
255
     * @param bool[] $haspartials the result of loading partial data elements
256
     * @param renderer_base $output typically, the renderer that's calling this function
257
     * @return bool if the cm has format data
258
     */
259
    protected function add_format_data(stdClass &$data, array $haspartials, renderer_base $output): bool {
260
        $result = false;
261
        // Legacy indentation.
262
        if (!empty($this->mod->indent) && $this->format->uses_indentation()) {
263
            $data->indent = $this->mod->indent;
264
            if ($this->mod->indent > 15) {
265
                $data->hugeindent = true;
266
                $result = true;
267
            }
268
        }
269
        // Stealth and hidden from student.
270
        if (!$this->mod->visible) {
271
            // This module is hidden but current user has capability to see it.
272
            $data->modhiddenfromstudents = true;
273
            $result = true;
274
        } else if ($this->mod->is_stealth()) {
275
            // This module is available but is normally not displayed on the course page
276
            // (this user can see it because they can manage it).
277
            $data->modstealth = true;
278
            $result = true;
279
        }
280
        // Special inline activity format.
281
        if (
282
            $this->mod->has_custom_cmlist_item() &&
283
            !$haspartials['availability'] &&
284
            !$haspartials['completion'] &&
285
            !$haspartials['dates'] &&
286
            !$haspartials['groupmode'] &&
287
            !isset($data->modhiddenfromstudents) &&
288
            !isset($data->modstealth) &&
289
            !$this->format->show_editor()
290
        ) {
291
            $data->modinline = true;
292
            $result = true;
293
        }
294
        return $result;
295
    }
296
 
297
    /**
298
     * Add course editor attributes to the data structure.
299
     *
300
     * @param stdClass $data the current cm data reference
301
     * @param renderer_base $output typically, the renderer that's calling this function
302
     * @return bool if the cm has editor data
303
     */
304
    protected function add_editor_data(stdClass &$data, renderer_base $output): bool {
305
        $course = $this->format->get_course();
306
        $coursecontext = context_course::instance($course->id);
307
        $editcaps = [];
308
        if (has_capability('moodle/course:activityvisibility', $coursecontext)) {
309
            $editcaps = ['moodle/course:activityvisibility'];
310
        }
311
        if (!$this->format->show_editor($editcaps)) {
312
            return false;
313
        }
314
        $returnsection = $this->format->get_sectionnum();
315
        // Edit actions.
316
        $controlmenu = new $this->controlmenuclass(
317
            $this->format,
318
            $this->section,
319
            $this->mod,
320
            $this->displayoptions
321
        );
322
        $data->controlmenu = $controlmenu->export_for_template($output);
323
        if (!$this->format->supports_components()) {
324
            // Add the legacy YUI move link.
325
            $data->moveicon = course_get_cm_move($this->mod, $returnsection);
326
        }
327
        return true;
328
    }
329
 
330
    /**
331
     * Add group mode information to the data structure.
332
     *
333
     * @param stdClass $data the current cm data reference
334
     * @param renderer_base $output typically, the renderer that's calling this function
335
     * @return bool the module has group mode information
336
     */
337
    protected function add_groupmode_data(stdClass &$data, renderer_base $output): bool {
338
        $groupmode = new $this->groupmodeclass($this->format, $this->section, $this->mod);
339
        $data->groupmodeinfo = $groupmode->export_for_template($output);
340
        return !empty($data->groupmodeinfo);
341
    }
342
 
343
    /**
344
     * Add visibility information to the data structure.
345
     *
346
     * @param stdClass $data the current cm data reference
347
     * @param renderer_base $output typically, the renderer that's calling this function
348
     * @return bool if the cm has visibility data
349
     */
350
    protected function add_visibility_data(stdClass &$data, renderer_base $output): bool {
351
        $visibility = new $this->visibilityclass($this->format, $this->section, $this->mod);
352
        $templatedata = $visibility->export_for_template($output);
353
        if ($templatedata) {
354
            $data->visibility = $templatedata;
355
            return true;
356
        }
357
        return false;
358
    }
359
 
360
    /**
361
     * Returns the CSS classes for the activity name/content
362
     *
363
     */
364
    protected function load_classes() {
365
        $mod = $this->mod;
366
 
367
        $linkclasses = '';
368
        $textclasses = '';
369
        if ($mod->uservisible) {
370
            $info = new info_module($mod);
371
            $conditionalhidden = !$info->is_available_for_all();
372
            $accessiblebutdim = (!$mod->visible || $conditionalhidden) &&
373
                has_capability('moodle/course:viewhiddenactivities', $mod->context);
374
            if ($accessiblebutdim && $conditionalhidden) {
375
                $linkclasses .= ' conditionalhidden';
376
                $textclasses .= ' conditionalhidden';
377
            }
378
        }
379
        $this->displayoptions['linkclasses'] = $linkclasses;
380
        $this->displayoptions['textclasses'] = $textclasses;
381
        $this->displayoptions['onclick'] = htmlspecialchars_decode($mod->onclick, ENT_QUOTES);;
382
    }
383
 
384
    /**
385
     * Get the activity link classes.
386
     *
387
     * @return string the activity link classes.
388
     */
389
    public function get_link_classes(): string {
390
        return $this->displayoptions['linkclasses'] ?? '';
391
    }
392
 
393
    /**
394
     * Get the activity text/description classes.
395
     *
396
     * @return string the activity text classes.
397
     */
398
    public function get_text_classes(): string {
399
        return $this->displayoptions['textclasses'] ?? '';
400
    }
401
 
402
    /**
403
     * Get the activity onclick code.
404
     *
405
     * @return string the activity onclick.
406
     */
407
    public function get_onclick_code(): string {
408
        return $this->displayoptions['onclick'];
409
    }
410
}