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
 * Extend this class when creating new layouts.
19
 *
20
 * @package    block_dash
21
 * @copyright  2019 bdecent gmbh <https://bdecent.de>
22
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 */
24
 
25
namespace block_dash\local\layout;
26
 
27
use block_dash\local\data_grid\data\data_collection_interface;
28
use block_dash\local\data_grid\data\field;
29
use block_dash\local\data_grid\data\strategy\data_strategy_interface;
30
use block_dash\local\data_grid\data\strategy\standard_strategy;
31
use block_dash\local\data_grid\field\attribute\context_attribute;
32
use block_dash\local\data_grid\field\attribute\identifier_attribute;
33
use block_dash\local\paginator;
34
use block_dash\local\data_source\data_source_interface;
35
use block_dash\local\data_source\form\preferences_form;
36
use html_writer;
37
use moodle_url;
38
 
39
/**
40
 * Extend this class when creating new layouts.
41
 *
42
 * Then register the layout in a lib.php function: pluginname_register_layouts(). See blocks/dash/lib.php for an
43
 * example.
44
 *
45
 * @package block_dash
46
 */
47
abstract class abstract_layout implements layout_interface, \templatable {
48
 
49
    /**
50
     * @var int Used for creating unique checkbox controller group IDs.
51
     */
52
    private static $currentgroupid = null;
53
 
54
    /**
55
     * The data source used as a data/configuration source for this layout.
56
     *
57
     * @var data_source_interface
58
     */
59
    private $datasource;
60
 
61
    /**
62
     * Layout constructor.
63
     *
64
     * @param data_source_interface $datasource
65
     */
66
    public function __construct(data_source_interface $datasource) {
67
        $this->datasource = $datasource;
68
    }
69
 
70
    /**
71
     * If the layout supports field sorting.
72
     *
73
     * @return mixed
74
     */
75
    public function supports_sorting() {
76
        return false;
77
    }
78
 
79
    /**
80
     * If the layout supports options.
81
     */
82
    public function supports_download() {
83
        return false;
84
    }
85
 
86
    /**
87
     * Get the data source used as a data/configuration source for this layout.
88
     *
89
     * @return data_source_interface
90
     */
91
    public function get_data_source() {
92
        return $this->datasource;
93
    }
94
 
95
    /**
96
     * Get data strategy.
97
     *
98
     * @return data_strategy_interface
99
     */
100
    public function get_data_strategy() {
101
        return new standard_strategy();
102
    }
103
 
104
    /**
105
     * Modify objects before data is retrieved in the data source. This allows the layout to make decisions on the
106
     * data source and data grid.
107
     */
108
    public function before_data() {
109
 
110
    }
111
 
112
    /**
113
     * Modify objects after data is retrieved in the data source. This allows the layout to make decisions on the
114
     * data source and data grid.
115
     *
116
     * @param data_collection_interface $datacollection
117
     */
118
    public function after_data(data_collection_interface $datacollection) {
119
 
120
    }
121
 
122
    /**
123
     * Add form elements to the preferences form when a user is configuring a block.
124
     *
125
     * This extends the form built by the data source. When a user chooses a layout, specific form elements may be
126
     * displayed after a quick refresh of the form.
127
     *
128
     * Be sure to call parent::build_preferences_form() if you override this method.
129
     *
130
     * @param \moodleform $form
131
     * @param \MoodleQuickForm $mform
132
     * @throws \coding_exception
133
     */
134
    public function build_preferences_form(\moodleform $form, \MoodleQuickForm $mform) {
135
        global $OUTPUT;
136
 
137
        self::$currentgroupid = random_int(1, 10000);
138
 
139
        $filtercollection = $this->get_data_source()->get_filter_collection();
140
 
141
        if ($form->get_tab() == preferences_form::TAB_FIELDS) {
142
            if ($this->supports_field_visibility()) {
143
                $group = [];
144
                foreach ($this->get_data_source()->get_sorted_fields() as $availablefield) {
145
                    if ($availablefield->has_attribute(identifier_attribute::class)) {
146
                        continue;
147
                    }
148
 
149
                    if ($availablefield->has_attribute(context_attribute::class)) {
150
                        continue;
151
                    }
152
 
153
                    $fieldname = 'config_preferences[available_fields][' . $availablefield->get_alias() .
154
                        '][visible]';
155
 
156
                    $title = $availablefield->get_table()->get_title();
157
 
158
                    $icon = $OUTPUT->pix_icon('i/dragdrop', get_string('dragitem', 'block_dash'), 'moodle',
159
                        ['class' => 'drag-handle']);
160
                    $title = $icon . '<b>' . $title . '</b>: ' . $availablefield->get_title();
161
 
162
                    $totaratitle = block_dash_is_totara() ? $title : null;
163
                    $group[] = $mform->createElement('advcheckbox', $fieldname, $title, $totaratitle, [
164
                        'group' => self::$currentgroupid, // For legacy add_checkbox_controller().
165
                        'data-togglegroup' => 'group' . self::$currentgroupid, // For checkbox_toggleall.
166
                        'data-toggle' => 'slave', // For checkbox_toggleall.
167
                        'data-action' => 'toggle', // For checkbox_toggleall.
168
                    ]);
169
                    $mform->setType($fieldname, PARAM_BOOL);
170
                }
171
                $mform->addGroup($group, 'available_fields', get_string('enabledfields', 'block_dash'),
172
                    [''], false);
173
 
174
                $this->add_checkbox_toggleall(self::$currentgroupid, $form, $mform);
175
 
176
                self::$currentgroupid++;
177
            }
178
        }
179
 
180
        if ($this->supports_filtering()) {
181
            if ($form->get_tab() == preferences_form::TAB_FILTERS) {
182
                $mform->addElement('static', 'filterslabel', '', '<b>' . get_string('enabledfilters', 'block_dash') . '</b>');
183
                $filtercollection->build_settings_form($form, $mform, 'filter', 'config_preferences[filters][%s]');
184
            }
185
        }
186
 
187
        if ($form->get_tab() == preferences_form::TAB_CONDITIONS) {
188
            $mform->addElement('static', 'conditionslabel', '', '<b>' . get_string('enabledconditions', 'block_dash') . '</b>');
189
            $filtercollection->build_settings_form($form, $mform, 'condition', 'config_preferences[filters][%s]');
190
        }
191
 
192
        if (!$this->supports_filtering() && $form->get_tab() == preferences_form::TAB_FILTERS) {
193
            $mform->addElement('html', $OUTPUT->notification(get_string('layoutdoesnotsupportfiltering', 'block_dash'), 'warning'));
194
        }
195
    }
196
 
197
    /**
198
     * Add button to select/deselect all checkboxes in group.
199
     *
200
     * @param string $uniqueid
201
     * @param \moodleform $form
202
     * @param \MoodleQuickForm $mform
203
     */
204
    private function add_checkbox_toggleall($uniqueid, \moodleform $form, \MoodleQuickForm $mform) {
205
        global $OUTPUT;
206
 
207
        if (class_exists('\core\output\checkbox_toggleall')) {
208
            $masterbutton = new \core\output\checkbox_toggleall('group' . $uniqueid, true, [], true);
209
 
210
            // Then you can export for template.
211
            $mform->addElement('static', 'toggleall' . $uniqueid, '', $OUTPUT->render($masterbutton));
212
        } else {
213
            // Moodle 3.7 and earlier support.
214
            $form->add_checkbox_controller($uniqueid);
215
        }
216
    }
217
 
218
    /**
219
     * Allows layout to modified preferences values before exporting to mustache template.
220
     *
221
     * @param array $preferences
222
     * @return array
223
     */
224
    public function process_preferences(array $preferences) {
225
        return $preferences;
226
    }
227
 
228
    /**
229
     * Get data for layout mustache template.
230
     *
231
     * @param \renderer_base $output
232
     * @return array|\stdClass
233
     * @throws \coding_exception
234
     */
235
    public function export_for_template(\renderer_base $output) {
236
        global $OUTPUT, $PAGE;
237
 
238
        $config = $this->get_data_source()->get_block_instance()->config;
239
        $noresulttxt = \html_writer::tag('p', get_string('noresults'), ['class' => 'text-muted']);
240
 
241
        $templatedata = [
242
            'error' => '',
243
            'paginator' => '',
244
            'data' => null,
245
            'uniqueid' => uniqid(),
246
            'is_totara' => block_dash_is_totara(),
247
            'bootstrap3' => get_config('block_dash', 'bootstrap_version') == 3,
248
            'bootstrap4' => get_config('block_dash', 'bootstrap_version') == 4,
249
            'noresult' => (isset($config->emptystate))
250
                ? format_text($config->emptystate['text'], FORMAT_HTML, ['noclean' => true]) : $noresulttxt,
251
        ];
252
 
253
        if (!empty($this->get_data_source()->get_all_preferences())) {
254
            try {
255
                $templatedata['data'] = $this->get_data_source()->get_data();
256
            } catch (\Exception $e) {
257
                $error = \html_writer::tag('p', get_string('databaseerror', 'block_dash'));
258
                if (is_siteadmin()) {
259
                    $error .= \html_writer::tag('p', $e->getMessage());
260
                }
261
 
262
                $templatedata['error'] .= $OUTPUT->notification($error, 'error');
263
            }
264
 
265
            if ($this->get_data_source()->get_paginator()->get_page_count() > 1) {
266
                $templatedata['paginator'] = $OUTPUT->render_from_template(paginator::TEMPLATE, $this->get_data_source()
267
                    ->get_paginator()
268
                    ->export_for_template($OUTPUT));
269
            }
270
        }
271
 
272
        $layout = isset($config->preferences['layout']) ? $config->preferences['layout'] : '';
273
        $formhtml = $this->get_data_source()->get_filter_collection()->create_form_elements('', $layout);
274
        // Get downloads butttons.
275
        $downloadcontent = '';
276
        if ($this->supports_download() && $this->get_data_source()->get_preferences('exportdata')) {
277
            $downloadoptions = [];
278
            $options = [];
279
            $downloadlist = '';
280
            $options['sesskey'] = sesskey();
281
            $options["download"] = "csv";
282
            $button = $OUTPUT->single_button(new moodle_url($PAGE->url, $options), get_string("downloadcsv", 'block_dash'), 'get');
283
            $downloadoptions[] = html_writer::tag('li', $button, ['class' => 'reportoption list-inline-item']);
284
 
285
            $options["download"] = "xls";
286
            $button = $OUTPUT->single_button(new moodle_url($PAGE->url, $options), get_string("downloadexcel"), 'get');
287
            $downloadoptions[] = html_writer::tag('li', $button, ['class' => 'reportoption list-inline-item']);
288
 
289
            $downloadlist .= html_writer::tag('ul', implode('', $downloadoptions), ['class' => 'list-inline inline']);
290
            $downloadlist .= html_writer::tag('div', '', ['class' => 'clearfloat']);
291
            $downloadcontent .= html_writer::tag('div', $downloadlist, ['class' => 'downloadreport mt-1']);
292
        }
293
 
294
        if (!is_null($templatedata['data'])) {
295
            $templatedata = array_merge($templatedata, [
296
                'filter_form_html' => $formhtml,
297
                'downloadcontent' => $downloadcontent,
298
                'supports_filtering' => $this->supports_filtering(),
299
                'supports_download' => $this->supports_download(),
300
                'supports_pagination' => $this->supports_pagination(),
301
                'preferences' => $this->process_preferences($this->get_data_source()->get_all_preferences()),
302
            ]);
303
        }
304
        return $templatedata;
305
    }
306
 
307
    /**
308
     * Map data.
309
     *
310
     * @param array $mapping
311
     * @param data_collection_interface $datacollection
312
     * @return data_collection_interface
313
     */
314
    protected function map_data($mapping, data_collection_interface $datacollection) {
315
        foreach ($mapping as $newname => $fieldname) {
316
            if ($fieldname && !is_array($fieldname) && isset($datacollection[$fieldname])) {
317
                $datacollection->add_data(new field($newname, $datacollection[$fieldname], true));
318
            } else if ($fieldname && is_array($fieldname)) {
319
                $value = array_map(function($field) use ($datacollection) {
320
                    return $datacollection[$field];
321
                }, $fieldname);
322
                $datacollection->add_data(new field($newname, implode(" ", $value), true));
323
            }
324
        }
325
        return $datacollection;
326
    }
327
 
328
    /**
329
     * Returns supported icons.
330
     *
331
     * @return array
332
     */
333
    protected function get_icon_list() {
334
        global $PAGE;
335
 
336
        $icons = [];
337
 
338
        if (isset($PAGE->theme->iconsystem)) {
339
            if ($iconsystem = \core\output\icon_system::instance($PAGE->theme->iconsystem)) {
340
                if ($iconsystem instanceof \core\output\icon_system_fontawesome) {
341
                    foreach ($iconsystem->get_icon_name_map() as $pixname => $faname) {
342
                        $icons[$faname] = $pixname;
343
                    }
344
                }
345
            }
346
        } else if (block_dash_is_totara()) {
347
            foreach (\core\output\flex_icon_helper::get_icons($PAGE->theme->name) as $iconkey => $icon) {
348
                $icons[$iconkey] = $iconkey;
349
            }
350
        }
351
 
352
        return $icons;
353
    }
354
}