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
namespace tool_brickfield\local\tool;
18
 
19
use tool_brickfield\manager;
20
 
21
/**
22
 * Brickfield accessibility tool base class.
23
 *
24
 * All common properties and methods for all tool types.
25
 *
26
 * @package     tool_brickfield
27
 * @copyright  2020 onward: Brickfield Education Labs, www.brickfield.ie
28
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
29
 */
30
abstract class tool {
31
 
32
    /** @var string[] All of the tools provided. */
33
    const TOOLNAMES = ['errors', 'activityresults', 'checktyperesults', 'printable', 'advanced'];
34
 
35
    /** @var string base64 bitmap image type */
36
    const BASE64_BMP = 'data:image/bmp;base64';
37
 
38
    /** @var string base64 gif image type */
39
    const BASE64_GIF = 'data:image/gif;base64';
40
 
41
    /** @var string base64 jpg image type */
42
    const BASE64_JPG = 'data:image/jpeg;base64';
43
 
44
    /** @var string base64 png image type */
45
    const BASE64_PNG = 'data:image/png;base64';
46
 
47
    /** @var string base64 svg image type */
48
    const BASE64_SVG = 'data:image/svg+xml;base64';
49
 
50
    /** @var string base64 webp image type */
51
    const BASE64_WEBP = 'data:image/webp;base64';
52
 
53
    /** @var string base64 ico image type */
54
    const BASE64_ICO = 'data:image/x-icon;base64';
55
 
56
    /** @var null Generic object for data used in tool renderers/templates. */
57
    private $data = null;
58
 
59
    /** @var  filter Any filter being used for tool display. */
60
    private $filter;
61
 
62
    /** @var string Error message if there is one. */
63
    private $errormessage = '';
64
 
65
    /**
66
     * Get a mapping of tool shortname => class name.
67
     *
68
     * @return  string[]
69
     */
70
    protected static function get_tool_classnames(): array {
71
        $tools = [];
72
 
73
        foreach (self::TOOLNAMES as $toolname) {
74
            $tools[$toolname] = "tool_brickfield\\local\\tool\\{$toolname}";
75
        }
76
 
77
        return $tools;
78
    }
79
 
80
    /**
81
     * Return an array with one of each tool instance.
82
     *
83
     * @return tool[]
84
     */
85
    public static function build_all_accessibilitytools(): array {
86
        return array_map(function($classname) {
87
            return new $classname();
88
        }, self::get_tool_classnames());
89
    }
90
 
91
    /**
92
     * Get a list of formal tool names for each tool.
93
     *
94
     * @return  string[]
95
     */
96
    public static function get_tool_names(): array {
97
        return array_map(function($classname) {
98
            return $classname::toolname();
99
        }, self::get_tool_classnames());
100
    }
101
 
102
    /**
103
     * Provide a lowercase name identifying this plugin. Should really be the same as the directory name.
104
     * @return string
105
     */
106
    abstract public function pluginname();
107
 
108
    /**
109
     * Provide a name for this tool, suitable for display on pages.
110
     * @return mixed
111
     */
112
    abstract public static function toolname();
113
 
114
    /**
115
     * Provide a short name for this tool, suitable for menus and selectors.
116
     * @return mixed
117
     */
118
    abstract public static function toolshortname();
119
 
120
    /**
121
     * Fetch the data for renderer / template display. Classes must implement this.
122
     * @return \stdClass
123
     */
124
    abstract protected function fetch_data(): \stdClass;
125
 
126
    /**
127
     * Return the data needed for the renderer.
128
     * @return \stdClass
129
     * @throws \coding_exception
130
     */
131
    public function get_data(): \stdClass {
132
        if (!$this->filter) {
133
            throw new \coding_exception('Filter has not been set.');
134
        }
135
 
136
        if (empty($this->data)) {
137
            $this->data = $this->fetch_data();
138
        }
139
 
140
        return $this->data;
141
    }
142
 
143
    /**
144
     * Implementing class should set the 'valid' property when get_data is called.
145
     * @return bool
146
     */
147
    public function data_is_valid(): bool {
148
        $data = $this->get_data();
149
        return (!empty($data->valid));
150
    }
151
 
152
    /**
153
     * Implementing class should set an error string if data is invalidated in 'get_data';
154
     * @return string
155
     */
156
    public function data_error(): string {
157
        if (!$this->data_is_valid()) {
158
            return $this->data->error;
159
        } else {
160
            return '';
161
        }
162
    }
163
 
164
    /**
165
     * Setter for filter property.
166
     * @param filter $filter
167
     * @throws \coding_exception
168
     */
169
    public function set_filter(filter $filter): void {
170
        if ($this->filter) {
171
            throw new \coding_exception('Filter can only be set once.');
172
        }
173
 
174
        $this->filter = $filter;
175
    }
176
 
177
    /**
178
     * Getter for filter property.
179
     * @return filter|null
180
     */
181
    public function get_filter(): ?filter {
182
        return $this->filter;
183
    }
184
 
185
    /**
186
     * Returns the output target for this tool's filter.
187
     *
188
     * @return string
189
     * @throws \coding_exception
190
     */
191
    public function get_output_target() {
192
        $filter = $this->get_filter();
193
        if (!$filter) {
194
            throw new \coding_exception('Filter has not been set.');
195
        }
196
        return $filter->target;
197
    }
198
 
199
    /**
200
     * Get the HTML output for display.
201
     *
202
     * @return mixed
203
     */
204
    public function get_output() {
205
        global $PAGE;
206
 
207
        $data = $this->get_data();
208
        $filter = $this->get_filter();
209
        $renderer = $PAGE->get_renderer('tool_brickfield', $this->pluginname());
210
        return $renderer->display($data, $filter);
211
    }
212
 
213
    /**
214
     * Return the defined toolname.
215
     *
216
     * @return mixed
217
     */
218
    public function get_toolname(): string {
219
        return static::toolname();
220
    }
221
 
222
    /**
223
     * Return the defined toolshortname.
224
     *
225
     * @return mixed
226
     */
227
    public function get_toolshortname(): string {
228
        return static::toolshortname();
229
    }
230
 
231
    /**
232
     * Verify that accessibility tools can be accessed in the provided context.
233
     * @param filter $filter
234
     * @param \context $context
235
     * @return bool
236
     * @throws \coding_exception
237
     * @throws \dml_exception
238
     */
239
    public function can_access(filter $filter, \context $context = null): bool {
240
        return $filter->can_access($context);
241
    }
242
 
243
    /**
244
     * Return any defined error message.
245
     *
246
     * @return string
247
     */
248
    public function get_error_message(): string {
249
        return $this->errormessage;
250
    }
251
 
252
    /**
253
     * Get module label for display
254
     * @param string $modulename
255
     * @return string
256
     * @throws \coding_exception
257
     */
258
    public static function get_module_label(string $modulename): string {
259
        if (get_string_manager()->string_exists('pluginname', $modulename)) {
260
            $modulename = get_string('pluginname', $modulename);
261
        } else {
262
            $modulename = get_string($modulename, manager::PLUGINNAME);
263
        }
264
        return($modulename);
265
    }
266
 
267
    /**
268
     * Get instance name for display
269
     * @param string $component
270
     * @param string $table
271
     * @param int $cmid
272
     * @param int $courseid
273
     * @param int $categoryid
274
     * @return string
275
     */
276
    public static function get_instance_name(string $component, string $table, ?int $cmid, ?int $courseid,
277
        ?int $categoryid): string {
278
        global $DB;
279
 
280
        $instancename = '';
281
        if (empty($component)) {
282
            return $instancename;
283
        }
284
        if ($component == 'core_course') {
285
            if (($table == 'course_categories') && ($categoryid != 0) && ($categoryid != null)) {
286
                $instancename = $DB->get_field($table, 'name', ['id' => $categoryid]);
287
                return get_string('category') . ' - ' . $instancename;
288
            }
289
            if (($courseid == 0) || ($courseid == null)) {
290
                return $instancename;
291
            }
292
            $thiscourse = get_fast_modinfo($courseid)->get_course();
293
            $instancename = $thiscourse->shortname;
294
        } else if ($component == 'core_question') {
295
            $instancename = get_string('questions', 'question');
296
        } else {
297
            if (($cmid == 0) || ($cmid == null)) {
298
                return $instancename;
299
            }
300
            $cm = get_fast_modinfo($courseid)->cms[$cmid];
301
            $instancename = $cm->name;
302
        }
303
        $instancename = static::get_module_label($component).' - '.$instancename;
304
        return($instancename);
305
    }
306
 
307
    /**
308
     * Provide arguments required for the toplevel page, using any provided filter.
309
     * @param filter|null $filter
310
     * @return array
311
     */
312
    public static function toplevel_arguments(filter $filter = null): array {
313
        if ($filter !== null) {
314
            return ['courseid' => $filter->courseid, 'categoryid' => $filter->categoryid];
315
        } else {
316
            return [];
317
        }
318
    }
319
 
320
    /**
321
     * Override this to return any tool specific perpage limits.
322
     * @param int $perpage
323
     * @return int
324
     */
325
    public function perpage_limits(int $perpage): int {
326
        return $perpage;
327
    }
328
 
329
    /**
330
     * Return array of base64 image formats.
331
     * @return array
332
     */
333
    public static function base64_img_array(): array {
334
        $base64 = [];
335
        $base64[] = self::BASE64_BMP;
336
        $base64[] = self::BASE64_GIF;
337
        $base64[] = self::BASE64_JPG;
338
        $base64[] = self::BASE64_PNG;
339
        $base64[] = self::BASE64_SVG;
340
        $base64[] = self::BASE64_WEBP;
341
        $base64[] = self::BASE64_ICO;
342
        return $base64;
343
    }
344
 
345
    /**
346
     * Detects if htmlcode contains base64 img data, for HTML display, such as errors page.
347
     * @param string $htmlcode
348
     * @return boolean
349
     */
350
    public static function base64_img_detected(string $htmlcode): bool {
351
        $detected = false;
352
 
353
        // Grab defined base64 img array.
354
        $base64 = self::base64_img_array();
355
        foreach ($base64 as $type) {
356
            // Need to detect this within an img tag.
357
            $pos = stripos($htmlcode, '<img src="'.$type);
358
            if ($pos !== false) {
359
                $detected = true;
360
                return $detected;
361
            }
362
        }
363
        return $detected;
364
    }
365
 
366
    /**
367
     * Truncate base64-containing htmlcode for HTML display, such as errors page.
368
     * @param string $htmlcode
369
     * @return string
370
     */
371
    public static function truncate_base64(string $htmlcode): string {
372
        $newhtmlcode = '';
373
        // Parse HTML by " characters.
374
        $sections = explode('"', $htmlcode);
375
        $base64 = self::base64_img_array();
376
        foreach ($sections as $section) {
377
            foreach ($base64 as $type) {
378
                $pos = stripos($section, $type);
379
                if ($pos !== false) {
380
                    $section = substr($section, 0, $pos + strlen($type)).'...';
381
                }
382
            }
383
            $newhtmlcode .= $section.'"';
384
        }
385
        return $newhtmlcode;
386
    }
387
 
388
    /**
389
     * Return the correct language string for the provided check.
390
     *
391
     * @param string $check
392
     * @return string
393
     */
394
    public static function get_check_description(string $check): string {
395
        return get_string('checkdesc:' . str_replace('_', '', $check), manager::PLUGINNAME);
396
    }
397
}