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