Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1441 ariadna 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
namespace core_courseformat\output\local\content;
18
 
19
use core\context\course as context_course;
20
use core\output\action_menu;
21
use core\output\action_menu\link_secondary;
22
use core\output\named_templatable;
23
use core\output\pix_icon;
24
use core\output\renderable;
25
use core\output\renderer_base;
26
use core_courseformat\base as course_format;
27
use core_courseformat\output\local\courseformat_named_templatable;
28
use core\url;
29
use section_info;
30
use cm_info;
31
use stdClass;
32
 
33
/**
34
 * Base class to render course element controls.
35
 *
36
 * @package   core_courseformat
37
 * @copyright 2024 Amaia Anabitarte <amaia@moodle.com>
38
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
39
 */
40
abstract class basecontrolmenu implements named_templatable, renderable {
41
 
42
    use courseformat_named_templatable;
43
 
44
    /** @var course_format the course format class */
45
    protected $format;
46
 
47
    /** @var section_info the course section class */
48
    protected $section;
49
 
50
    /** @var cm_info the course module class */
51
    protected $mod;
52
 
53
    /** @var stdClass the course instance */
54
    protected stdClass $course;
55
 
56
    /** @var context_course the course context */
57
    protected $coursecontext;
58
 
59
    /** @var string the menu ID */
60
    protected $menuid;
61
 
62
    /** @var action_menu the action menu */
63
    protected $menu;
64
 
65
    /** @var url The base URL for the course or the section */
66
    protected url $baseurl;
67
 
68
    /**
69
     * Constructor.
70
     *
71
     * @param course_format $format the course format
72
     * @param section_info $section the section info
73
     * @param cm_info|null $mod the module info
74
     * @param string $menuid the ID value for the menu
75
     */
76
    public function __construct(course_format $format, section_info $section, ?cm_info $mod = null, string $menuid = '') {
77
        $this->format = $format;
78
        $this->section = $section;
79
        $this->mod = $mod;
80
        $this->menuid = $menuid;
81
        $this->course = $format->get_course();
82
        $this->coursecontext = $format->get_context();
83
        $this->baseurl = $format->get_view_url($format->get_sectionnum(), ['navigation' => true]);
84
    }
85
 
86
    /**
87
     * Change the default base URL to return after each action.
88
     *
89
     * @param url $baseurl
90
     */
91
    public function set_baseurl(url $baseurl) {
92
        $this->baseurl = $baseurl;
93
    }
94
 
95
    /**
96
     * Export this data so it can be used as the context for a mustache template.
97
     *
98
     * @param renderer_base $output typically, the renderer that's calling this function
99
     * @return null|array data context for a mustache template
100
     */
101
    public function export_for_template(renderer_base $output): ?stdClass {
102
        $menu = $this->get_action_menu($output);
103
        if (empty($menu)) {
104
            return new stdClass();
105
        }
106
 
107
        $data = (object)[
108
            'menu' => $output->render($menu),
109
            'hasmenu' => true,
110
            'id' => $this->menuid,
111
        ];
112
 
113
        return $data;
114
    }
115
 
116
    /**
117
     * Generate the action menu element.
118
     *
119
     * @param renderer_base $output typically, the renderer that's calling this function
120
     * @return action_menu|null the action menu or null if no action menu is available
121
     */
122
    public function get_action_menu(renderer_base $output): ?action_menu {
123
 
124
        if (!empty($this->menu)) {
125
            return $this->menu;
126
        }
127
 
128
        $this->menu = $this->get_default_action_menu($output);
129
        return $this->menu;
130
    }
131
 
132
    /**
133
     * Generate the default action menu.
134
     *
135
     * This method is public in case some block needs to modify the menu before output it.
136
     *
137
     * @param renderer_base $output typically, the renderer that's calling this function
138
     * @return action_menu|null the action menu
139
     */
140
    public function get_default_action_menu(renderer_base $output): ?action_menu {
141
        return null;
142
    }
143
 
144
    /**
145
     * Format control array into an action_menu.
146
     *
147
     * @param \renderer_base $output typically, the renderer that's calling this function
148
     * @return action_menu|null the action menu
149
     */
150
    protected function format_controls(array $controls): ?action_menu {
151
        if (empty($controls)) {
152
            return null;
153
        }
154
 
155
        $menu = new action_menu();
156
        $menu->set_kebab_trigger(get_string('edit'));
157
        $menu->attributes['class'] .= ' section-actions';
158
        $menu->attributes['data-sectionid'] = $this->section->id;
159
        foreach ($controls as $item) {
160
            // Actions not available for the user can be null.
161
            if ($item === null) {
162
                continue;
163
            }
164
 
165
            // TODO remove this if as part of MDL-83530.
166
            if (is_array($item)) {
167
                // Some third party formats from 4.5 and older can use array to define the action menu items.
168
                $item = $this->normalize_action_menu_link($item);
169
            }
170
 
171
            $menu->add($item);
172
        }
173
        return $menu;
174
    }
175
 
176
    /**
177
     * Nromalize the action menu item, or return null if it is not possible.
178
     *
179
     * Traditionally, this class uses array to define the action menu items,
180
     * for backward compatibility, this method will normalize the array into
181
     * the correct action_menu_link object.
182
     *
183
     * @todo Remove this method in Moodle 6.0 (MDL-83530).
184
     * @param array|null $itemdata the item data
185
     * @return void
186
     */
187
    private function normalize_action_menu_link(
188
        array|null $itemdata
189
    ): ?link_secondary {
190
        debugging(
191
            "Using arrays as action menu items is deprecated, use a compatible menu item instead.",
192
            DEBUG_DEVELOPER
193
        );
194
        if (empty($itemdata)) {
195
            return null;
196
        }
197
        $url = empty($itemdata['url']) ? '' : $itemdata['url'];
198
        $icon = empty($itemdata['icon']) ? '' : $itemdata['icon'];
199
        $name = empty($itemdata['name']) ? '' : $itemdata['name'];
200
        $attr = empty($itemdata['attr']) ? [] : $itemdata['attr'];
201
        $class = empty($itemdata['pixattr']['class']) ? '' : $itemdata['pixattr']['class'];
202
        return new link_secondary(
203
            url: new url($url),
204
            icon: new pix_icon($icon, '', null, ['class' => "smallicon " . $class]),
205
            text: $name,
206
            attributes: $attr,
207
        );
208
    }
209
 
210
    /**
211
     * Generate the edit control items of a section.
212
     *
213
     * This method must remain public until the final deprecation of section_edit_control_items.
214
     *
215
     * @return array of edit control items
216
     */
217
    public function section_control_items() {
218
        return [];
219
    }
220
 
221
    /**
222
     * Adds a new control item after a given control item.
223
     *
224
     * If the control item is not found, the new control item is added at the beginning.
225
     *
226
     * @param array $controls array of edit control items
227
     * @param string $aftername name of the control item after which the new control item will be added
228
     * @param string $newkey key of the new control item
229
     * @param mixed $newcontrol new control item to be added (anything compatible with an action menu or null)
230
     */
231
    protected function add_control_after(array $controls, string $aftername, string $newkey, mixed $newcontrol): array {
232
        if (!array_key_exists($aftername, $controls)) {
233
            return array_merge([$newkey => $newcontrol], $controls);
234
        }
235
        $newcontrols = [];
236
        $found = false;
237
        foreach ($controls as $keyname => $control) {
238
            $newcontrols[$keyname] = $control;
239
            if ($keyname === $aftername) {
240
                $newcontrols[$newkey] = $newcontrol;
241
                $found = true;
242
            }
243
        }
244
        if (!$found) {
245
            $newcontrols[$newkey] = $newcontrol;
246
        }
247
        return $newcontrols;
248
    }
249
}