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 section course format 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;
26
 
27
use context_course;
28
use core\output\named_templatable;
29
use core_courseformat\base as course_format;
30
use core_courseformat\output\local\courseformat_named_templatable;
31
use renderable;
32
use renderer_base;
33
use section_info;
34
use stdClass;
35
 
36
/**
37
 * Base class to render a course section.
38
 *
39
 * @package   core_courseformat
40
 * @copyright 2020 Ferran Recio <ferran@moodle.com>
41
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
42
 */
43
class section implements named_templatable, renderable {
44
    use courseformat_named_templatable;
45
 
46
    /** @var course_format the course format */
47
    protected $format;
48
 
49
    /** @var section_info the section info */
50
    protected $section;
51
 
52
    /** @var section header output class */
53
    protected $headerclass;
54
 
55
    /** @var cm list output class */
56
    protected $cmlistclass;
57
 
58
    /** @var section summary output class */
59
    protected $summaryclass;
60
 
61
    /** @var activities summary output class */
62
    protected $cmsummaryclass;
63
 
64
    /** @var section control menu output class */
65
    protected $controlclass;
66
 
67
    /** @var section availability output class */
68
    protected $availabilityclass;
69
 
70
    /** @var optional move here output class */
71
    protected $movehereclass;
72
 
73
    /** @var optional visibility output class */
74
    protected $visibilityclass;
75
 
76
    /** @var bool if the title is hidden for some reason */
77
    protected $hidetitle = false;
78
 
79
    /** @var bool if the title is hidden for some reason */
80
    protected $hidecontrols = false;
81
 
82
    /** @var bool if the section is considered stealth */
83
    protected $isstealth = false;
84
 
85
    /** @var string control menu class. */
86
    protected $controlmenuclass;
87
 
88
    /**
89
     * Constructor.
90
     *
91
     * @param course_format $format the course format
92
     * @param section_info $section the section info
93
     */
94
    public function __construct(course_format $format, section_info $section) {
95
        $this->format = $format;
96
        $this->section = $section;
97
 
98
        if ($section->section > $format->get_last_section_number()) {
99
            $this->isstealth = true;
100
        }
101
 
102
        // Load output classes names from format.
103
        $this->headerclass = $format->get_output_classname('content\\section\\header');
104
        $this->cmlistclass = $format->get_output_classname('content\\section\\cmlist');
105
        $this->summaryclass = $format->get_output_classname('content\\section\\summary');
106
        $this->cmsummaryclass = $format->get_output_classname('content\\section\\cmsummary');
107
        $this->controlmenuclass = $format->get_output_classname('content\\section\\controlmenu');
108
        $this->availabilityclass = $format->get_output_classname('content\\section\\availability');
109
        $this->movehereclass = $format->get_output_classname('content\\section\\movehere');
110
        $this->visibilityclass = $format->get_output_classname('content\\section\\visibility');
111
    }
112
 
113
    /**
114
     * Hide the section title.
115
     *
116
     * This is used on blocks or in the home page where an isolated section is displayed.
117
     */
118
    public function hide_title(): void {
119
        $this->hidetitle = true;
120
    }
121
 
122
    /**
123
     * Hide the section controls.
124
     *
125
     * This is used on blocks or in the home page where an isolated section is displayed.
126
     */
127
    public function hide_controls(): void {
128
        $this->hidecontrols = true;
129
    }
130
 
131
    /**
132
     * Export this data so it can be used as the context for a mustache template.
133
     *
134
     * @param renderer_base $output typically, the renderer that's calling this function
135
     * @return stdClass data context for a mustache template
136
     */
137
    public function export_for_template(renderer_base $output): stdClass {
138
        global $USER, $PAGE;
139
 
140
        $format = $this->format;
141
        $course = $format->get_course();
142
        $section = $this->section;
143
 
144
        $summary = new $this->summaryclass($format, $section);
145
 
146
        $data = (object)[
147
            'num' => $section->section ?? '0',
148
            'id' => $section->id,
149
            'sectionreturnid' => $format->get_sectionnum(),
150
            'insertafter' => false,
151
            'summary' => $summary->export_for_template($output),
152
            'highlightedlabel' => $format->get_section_highlighted_name(),
153
            'sitehome' => $course->id == SITEID,
154
            'editing' => $PAGE->user_is_editing(),
155
            'displayonesection' => ($course->id != SITEID && !is_null($format->get_sectionid())),
156
        ];
157
 
158
        $haspartials = [];
159
        $haspartials['availability'] = $this->add_availability_data($data, $output);
160
        $haspartials['visibility'] = $this->add_visibility_data($data, $output);
161
        $haspartials['editor'] = $this->add_editor_data($data, $output);
162
        $haspartials['header'] = $this->add_header_data($data, $output);
163
        $haspartials['cm'] = $this->add_cm_data($data, $output);
164
        $this->add_format_data($data, $haspartials, $output);
165
 
166
        return $data;
167
    }
168
 
169
    /**
170
     * Add the section header to the data structure.
171
     *
172
     * @param stdClass $data the current cm data reference
173
     * @param renderer_base $output typically, the renderer that's calling this function
174
     * @return bool if the cm has name data
175
     */
176
    protected function add_header_data(stdClass &$data, renderer_base $output): bool {
177
        if (!empty($this->hidetitle)) {
178
            return false;
179
        }
180
 
181
        $section = $this->section;
182
        $format = $this->format;
183
 
184
        $header = new $this->headerclass($format, $section);
185
        $headerdata = $header->export_for_template($output);
186
 
187
        // When a section is displayed alone the title goes over the section, not inside it.
188
        if ($section->section != 0 && $section->section == $format->get_sectionnum()) {
189
            $data->singleheader = $headerdata;
190
        } else {
191
            $data->header = $headerdata;
192
        }
193
        return true;
194
    }
195
 
196
    /**
197
     * Add the section cm list to the data structure.
198
     *
199
     * @param stdClass $data the current cm data reference
200
     * @param renderer_base $output typically, the renderer that's calling this function
201
     * @return bool if the cm has name data
202
     */
203
    protected function add_cm_data(stdClass &$data, renderer_base $output): bool {
204
        $result = false;
205
 
206
        $section = $this->section;
207
        $format = $this->format;
208
 
209
        $showsummary = ($section->section != 0 &&
210
            $section->section != $format->get_sectionnum() &&
211
            $format->get_course_display() == COURSE_DISPLAY_MULTIPAGE &&
212
            !$format->show_editor()
213
        );
214
 
215
        $showcmlist = $section->uservisible;
216
 
217
        // Add activities summary if necessary.
218
        if ($showsummary) {
219
            $cmsummary = new $this->cmsummaryclass($format, $section);
220
            $data->cmsummary = $cmsummary->export_for_template($output);
221
            $data->onlysummary = true;
222
            $result = true;
223
 
224
            if (!$format->is_section_current($section)) {
225
                // In multipage, only the current section (and the section zero) has elements.
226
                $showcmlist = false;
227
            }
228
        }
229
        // Add the cm list.
230
        if ($showcmlist) {
231
            $cmlist = new $this->cmlistclass($format, $section);
232
            $data->cmlist = $cmlist->export_for_template($output);
233
            $result = true;
234
        }
235
        return $result;
236
    }
237
 
238
    /**
239
     * Add the section availability to the data structure.
240
     *
241
     * @param stdClass $data the current cm data reference
242
     * @param renderer_base $output typically, the renderer that's calling this function
243
     * @return bool if the cm has name data
244
     */
245
    protected function add_availability_data(stdClass &$data, renderer_base $output): bool {
246
        $availability = new $this->availabilityclass($this->format, $this->section);
247
        $data->availability = $availability->export_for_template($output);
248
        $data->restrictionlock = !empty($this->section->availableinfo);
249
        $data->hasavailability = $availability->has_availability($output);
250
        return true;
251
    }
252
 
253
    /**
254
     * Add the section vibility information to the data structure.
255
     *
256
     * @param stdClass $data the current cm data reference
257
     * @param renderer_base $output typically, the renderer that's calling this function
258
     * @return bool if the cm has name data
259
     */
260
    protected function add_visibility_data(stdClass &$data, renderer_base $output): bool {
261
        global $USER;
262
        $result = false;
263
        // Check if it is a stealth sections (orphaned).
264
        if ($this->isstealth) {
265
            $data->isstealth = true;
266
            $data->ishidden = true;
267
            $result = true;
268
        }
269
        if (!$this->section->visible) {
270
            $data->ishidden = true;
271
            $course = $this->format->get_course();
272
            $context = context_course::instance($course->id);
273
            if (has_capability('moodle/course:viewhiddensections', $context, $USER)) {
274
                $result = true;
275
            }
276
        }
277
        /* @var \core_courseformat\output\local\content\section\visibility $visibility By default the visibility class used
278
         * here but can be overriden by any course format */
279
        $visibility = new $this->visibilityclass($this->format, $this->section);
280
        $data->visibility = $visibility->export_for_template($output);
281
        return $result;
282
    }
283
 
284
    /**
285
     * Add the section editor attributes to the data structure.
286
     *
287
     * @param stdClass $data the current cm data reference
288
     * @param renderer_base $output typically, the renderer that's calling this function
289
     * @return bool if the cm has name data
290
     */
291
    protected function add_editor_data(stdClass &$data, renderer_base $output): bool {
292
        $course = $this->format->get_course();
293
        $coursecontext = context_course::instance($course->id);
294
        $editcaps = [];
295
        if (has_capability('moodle/course:sectionvisibility', $coursecontext)) {
296
            $editcaps = ['moodle/course:sectionvisibility'];
297
        }
298
        if (!$this->format->show_editor($editcaps)) {
299
            return false;
300
        }
301
 
302
        // In a single section page the control menu is located in the page header.
303
        if (empty($this->hidecontrols) && $this->format->get_sectionid() != $this->section->id) {
304
            $controlmenu = new $this->controlmenuclass($this->format, $this->section);
305
            $data->controlmenu = $controlmenu->export_for_template($output);
306
        }
307
        if (!$this->isstealth) {
308
            $data->cmcontrols = $output->course_section_add_cm_control(
309
                $course,
310
                $this->section->section,
311
                $this->format->get_sectionnum()
312
            );
313
        }
314
        return true;
315
    }
316
 
317
    /**
318
     * Add the section format attributes to the data structure.
319
     *
320
     * @param stdClass $data the current cm data reference
321
     * @param bool[] $haspartials the result of loading partial data elements
322
     * @param renderer_base $output typically, the renderer that's calling this function
323
     * @return bool if the cm has name data
324
     */
325
    protected function add_format_data(stdClass &$data, array $haspartials, renderer_base $output): bool {
326
        $section = $this->section;
327
        $format = $this->format;
328
 
329
        $data->iscoursedisplaymultipage = ($format->get_course_display() == COURSE_DISPLAY_MULTIPAGE);
330
 
331
        if ($data->num === 0 && !$data->iscoursedisplaymultipage) {
332
            $data->collapsemenu = true;
333
        }
334
 
335
        $data->contentcollapsed = $this->is_section_collapsed();
336
 
337
        if ($format->is_section_current($section)) {
338
            $data->iscurrent = true;
339
            $data->currentlink = get_accesshide(
340
                get_string('currentsection', 'format_' . $format->get_format())
341
            );
342
        }
343
        return true;
344
    }
345
 
346
    /**
347
     * Returns true if the current section should be shown collapsed.
348
     *
349
     * @return bool
350
     */
351
    protected function is_section_collapsed(): bool {
352
        global $PAGE;
353
 
354
        $contentcollapsed = false;
355
        $preferences = $this->format->get_sections_preferences();
356
        if (isset($preferences[$this->section->id])) {
357
            $sectionpreferences = $preferences[$this->section->id];
358
            if (!empty($sectionpreferences->contentcollapsed)) {
359
                $contentcollapsed = true;
360
            }
361
        }
362
 
363
        // No matter if the user's preference was to collapse the section or not: If the
364
        // 'expandsection' parameter has been specified, it will be shown uncollapsed.
365
        $expandsection = $PAGE->url->get_param('expandsection');
366
        if ($expandsection !== null && $this->section->section == $expandsection) {
367
            $contentcollapsed = false;
368
        }
369
        return $contentcollapsed;
370
    }
371
}