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
use core_external\external_api;
18
use core_external\external_function_parameters;
19
use core_external\external_multiple_structure;
20
use core_external\external_single_structure;
21
use core_external\external_value;
22
 
23
/**
24
 * Web service related functions
25
 *
26
 * @package    core
27
 * @category   external
28
 * @copyright  2012 Jerome Mouneyrac <jerome@moodle.com>
29
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
30
 * @since Moodle 2.4
31
 */
32
class core_external extends external_api {
33
 
34
 
35
    /**
36
     * Format the received string parameters to be sent to the core get_string() function.
37
     *
38
     * @param array $stringparams
39
     * @return object|string
40
     * @since Moodle 2.4
41
     */
42
    public static function format_string_parameters($stringparams) {
43
        // Check if there are some string params.
44
        $strparams = new stdClass();
45
        if (!empty($stringparams)) {
46
            // There is only one string parameter.
47
            if (count($stringparams) == 1) {
48
                $stringparam = array_pop($stringparams);
49
                if (isset($stringparam['name'])) {
50
                    $strparams->{$stringparam['name']} = $stringparam['value'];
51
                } else {
52
                    // It is a not named string parameter.
53
                    $strparams = $stringparam['value'];
54
                }
55
            } else {
56
                // There are more than one parameter.
57
                foreach ($stringparams as $stringparam) {
58
 
59
                    // If a parameter is unnamed throw an exception
60
                    // unnamed param is only possible if one only param is sent.
61
                    if (empty($stringparam['name'])) {
62
                        throw new moodle_exception('unnamedstringparam', 'webservice');
63
                    }
64
 
65
                    $strparams->{$stringparam['name']} = $stringparam['value'];
66
                }
67
            }
68
        }
69
        return $strparams;
70
    }
71
 
72
    /**
73
     * Returns description of get_string parameters
74
     *
75
     * @return external_function_parameters
76
     * @since Moodle 2.4
77
     */
78
    public static function get_string_parameters() {
79
        return new external_function_parameters(
80
            array('stringid' => new external_value(PARAM_STRINGID, 'string identifier'),
81
                  'component' => new external_value(PARAM_COMPONENT,'component', VALUE_DEFAULT, 'moodle'),
82
                  'lang' => new external_value(PARAM_LANG, 'lang', VALUE_DEFAULT, null),
83
                  'stringparams' => new external_multiple_structure (
84
                      new external_single_structure(array(
85
                          'name' => new external_value(PARAM_ALPHANUMEXT, 'param name
86
                            - if the string expect only one $a parameter then don\'t send this field, just send the value.', VALUE_OPTIONAL),
87
                          'value' => new external_value(PARAM_RAW,'param value'))),
88
                          'the definition of a string param (i.e. {$a->name})', VALUE_DEFAULT, array()
89
                   )
90
            )
91
        );
92
    }
93
 
94
    /**
95
     * Return a core get_string() call
96
     *
97
     * @param string $identifier string identifier
98
     * @param string $component string component
99
     * @param array $stringparams the string params
100
     * @return string
101
     * @since Moodle 2.4
102
     */
103
    public static function get_string($stringid, $component = 'moodle', $lang = null, $stringparams = array()) {
104
        $params = self::validate_parameters(self::get_string_parameters(),
105
                      array('stringid'=>$stringid, 'component' => $component, 'lang' => $lang, 'stringparams' => $stringparams));
106
 
107
        $stringmanager = get_string_manager();
108
        return $stringmanager->get_string($params['stringid'], $params['component'],
109
            core_external::format_string_parameters($params['stringparams']), $params['lang']);
110
    }
111
 
112
    /**
113
     * Returns description of get_string() result value
114
     *
115
     * @return \core_external\external_description
116
     * @since Moodle 2.4
117
     */
118
    public static function get_string_returns() {
119
        return new external_value(PARAM_RAW, 'translated string');
120
    }
121
 
122
    /**
123
     * Returns description of get_string parameters
124
     *
125
     * @return external_function_parameters
126
     * @since Moodle 2.4
127
     */
128
    public static function get_strings_parameters() {
129
        return new external_function_parameters(
130
            array('strings' => new external_multiple_structure (
131
                    new external_single_structure (array(
132
                        'stringid' => new external_value(PARAM_STRINGID, 'string identifier'),
133
                        'component' => new external_value(PARAM_COMPONENT, 'component', VALUE_DEFAULT, 'moodle'),
134
                        'lang' => new external_value(PARAM_LANG, 'lang', VALUE_DEFAULT, null),
135
                        'stringparams' => new external_multiple_structure (
136
                            new external_single_structure(array(
137
                                'name' => new external_value(PARAM_ALPHANUMEXT, 'param name
138
                                    - if the string expect only one $a parameter then don\'t send this field, just send the value.', VALUE_OPTIONAL),
139
                                'value' => new external_value(PARAM_RAW, 'param value'))),
140
                                'the definition of a string param (i.e. {$a->name})', VALUE_DEFAULT, array()
141
                        ))
142
                    )
143
                )
144
            )
145
        );
146
    }
147
 
148
    /**
149
     * Return multiple call to core get_string()
150
     *
151
     * @param array $strings strings to translate
152
     * @return array
153
     *
154
     * @since Moodle 2.4
155
     */
156
    public static function get_strings($strings) {
157
        $params = self::validate_parameters(self::get_strings_parameters(),
158
                      array('strings'=>$strings));
159
        $stringmanager = get_string_manager();
160
 
161
        $translatedstrings = array();
162
        foreach($params['strings'] as $string) {
163
 
164
            if (!empty($string['lang'])) {
165
                $lang = $string['lang'];
166
            } else {
167
                $lang = current_language();
168
            }
169
 
170
            $translatedstrings[] = array(
171
                'stringid' => $string['stringid'],
172
                'component' => $string['component'],
173
                'lang' => $lang,
174
                'string' => $stringmanager->get_string($string['stringid'], $string['component'],
175
                    core_external::format_string_parameters($string['stringparams']), $lang));
176
        }
177
 
178
        return $translatedstrings;
179
    }
180
 
181
    /**
182
     * Returns description of get_string() result value
183
     *
184
     * @return \core_external\external_description
185
     * @since Moodle 2.4
186
     */
187
    public static function get_strings_returns() {
188
        return new external_multiple_structure(
189
            new external_single_structure(array(
190
                'stringid' => new external_value(PARAM_STRINGID, 'string id'),
191
                'component' => new external_value(PARAM_COMPONENT, 'string component'),
192
                'lang' => new external_value(PARAM_LANG, 'lang'),
193
                'string' => new external_value(PARAM_RAW, 'translated string'))
194
            ));
195
    }
196
 
197
    /**
198
     * Returns description of get_user_dates parameters
199
     *
200
     * @return external_function_parameters
201
     */
202
    public static function get_user_dates_parameters() {
203
        return new external_function_parameters(
204
            [
205
                'contextid' => new external_value(
206
                    PARAM_INT,
207
                    'Context ID. Either use this value, or level and instanceid.',
208
                    VALUE_DEFAULT,
209
 
210
                ),
211
                'contextlevel' => new external_value(
212
                    PARAM_ALPHA,
213
                    'Context level. To be used with instanceid.',
214
                    VALUE_DEFAULT,
215
                    ''
216
                ),
217
                'instanceid' => new external_value(
218
                    PARAM_INT,
219
                    'Context instance ID. To be used with level',
220
                    VALUE_DEFAULT,
221
 
222
                ),
223
                'timestamps' => new external_multiple_structure (
224
                    new external_single_structure (
225
                        [
226
                            'timestamp' => new external_value(PARAM_INT, 'unix timestamp'),
227
                            'format' => new external_value(PARAM_TEXT, 'format string'),
228
                            'type' => new external_value(PARAM_PLUGIN, 'The calendar type', VALUE_DEFAULT),
229
                            'fixday' => new external_value(PARAM_INT, 'Remove leading zero for day', VALUE_DEFAULT, 1),
230
                            'fixhour' => new external_value(PARAM_INT, 'Remove leading zero for hour', VALUE_DEFAULT, 1),
231
                        ]
232
                    )
233
                )
234
            ]
235
        );
236
    }
237
 
238
    /**
239
     * Format an array of timestamps.
240
     *
241
     * @param int|null $contextid The contenxt id
242
     * @param string|null $contextlevel The context level
243
     * @param int|null $instanceid The instnace id for the context level
244
     * @param array $timestamps Timestamps to format
245
     * @return array
246
     */
247
    public static function get_user_dates($contextid, $contextlevel, $instanceid, $timestamps) {
248
        $params = self::validate_parameters(
249
            self::get_user_dates_parameters(),
250
            [
251
                'contextid' => $contextid,
252
                'contextlevel' => $contextlevel,
253
                'instanceid' => $instanceid,
254
                'timestamps' => $timestamps,
255
            ]
256
        );
257
 
258
        $context = self::get_context_from_params($params);
259
        self::validate_context($context);
260
 
261
        $formatteddates = array_map(function($timestamp) {
262
 
263
            $calendartype = $timestamp['type'];
264
            $fixday = !empty($timestamp['fixday']);
265
            $fixhour = !empty($timestamp['fixhour']);
266
            $calendar  = \core_calendar\type_factory::get_calendar_instance($calendartype);
267
            return $calendar->timestamp_to_date_string($timestamp['timestamp'], $timestamp['format'], 99, $fixday, $fixhour);
268
        }, $params['timestamps']);
269
 
270
        return ['dates' => $formatteddates];
271
    }
272
 
273
    /**
274
     * Returns description of get_user_dates() result value
275
     *
276
     * @return \core_external\external_description
277
     */
278
    public static function get_user_dates_returns() {
279
        return new external_single_structure(
280
            [
281
                'dates' => new external_multiple_structure (
282
                    new external_value(PARAM_TEXT, 'formatted dates strings')
283
                )
284
            ]
285
        );
286
    }
287
 
288
     /**
289
     * Returns description of get_component_strings parameters
290
     *
291
     * @return external_function_parameters
292
     * @since Moodle 2.4
293
     */
294
    public static function get_component_strings_parameters() {
295
        return new external_function_parameters(
296
            array('component' => new external_value(PARAM_COMPONENT, 'component'),
297
                  'lang' => new external_value(PARAM_LANG, 'lang', VALUE_DEFAULT, null),
298
            )
299
        );
300
    }
301
 
302
    /**
303
     * Return all lang strings of a component - call to core get_component_strings().
304
     *
305
     * @param string $component component name
306
     * @return array
307
     *
308
     * @since Moodle 2.4
309
     */
310
    public static function get_component_strings($component, $lang = null) {
311
 
312
        if (empty($lang)) {
313
            $lang = current_language();
314
        }
315
 
316
        $params = self::validate_parameters(self::get_component_strings_parameters(),
317
                      array('component'=>$component, 'lang' => $lang));
318
 
319
        $stringmanager = get_string_manager();
320
 
321
        $wsstrings = array();
322
        $componentstrings = $stringmanager->load_component_strings($params['component'], $params['lang']);
323
        foreach($componentstrings as $stringid => $string) {
324
            $wsstring = array();
325
            $wsstring['stringid'] = $stringid;
326
            $wsstring['string'] = $string;
327
            $wsstrings[] = $wsstring;
328
        }
329
 
330
        return $wsstrings;
331
    }
332
 
333
    /**
334
     * Returns description of get_component_strings() result value
335
     *
336
     * @return \core_external\external_description
337
     * @since Moodle 2.4
338
     */
339
    public static function get_component_strings_returns() {
340
        return new external_multiple_structure(
341
            new external_single_structure(array(
342
                'stringid' => new external_value(PARAM_STRINGID, 'string id'),
343
                'string' => new external_value(PARAM_RAW, 'translated string'))
344
            ));
345
    }
346
 
347
    /**
348
     * Returns description of get_fragment parameters
349
     *
350
     * @return external_function_parameters
351
     * @since Moodle 3.1
352
     */
353
    public static function get_fragment_parameters() {
354
        return new external_function_parameters(
355
            array(
356
                'component' => new external_value(PARAM_COMPONENT, 'Component for the callback e.g. mod_assign'),
357
                'callback' => new external_value(PARAM_ALPHANUMEXT, 'Name of the callback to execute'),
358
                'contextid' => new external_value(PARAM_INT, 'Context ID that the fragment is from'),
359
                'args' => new external_multiple_structure(
360
                    new external_single_structure(
361
                        array(
362
                            'name' => new external_value(PARAM_ALPHANUMEXT, 'param name'),
363
                            'value' => new external_value(PARAM_RAW, 'param value')
364
                        )
365
                    ), 'args for the callback are optional', VALUE_OPTIONAL
366
                )
367
            )
368
        );
369
    }
370
 
371
    /**
372
     * Get a HTML fragment for inserting into something. Initial use is for inserting mforms into
373
     * a page using AJAX.
374
     * This web service is designed to be called only via AJAX and not directly.
375
     * Callbacks that are called by this web service are responsible for doing the appropriate security checks
376
     * to access the information returned. This only does minimal validation on the context.
377
     *
378
     * @param string $component Name of the component.
379
     * @param string $callback Function callback name.
380
     * @param int $contextid Context ID this fragment is in.
381
     * @param array $args optional arguments for the callback.
382
     * @return array HTML and JavaScript fragments for insertion into stuff.
383
     * @since Moodle 3.1
384
     */
385
    public static function get_fragment($component, $callback, $contextid, $args = null) {
386
        global $OUTPUT, $PAGE;
387
 
388
        $params = self::validate_parameters(self::get_fragment_parameters(),
389
                array(
390
                    'component' => $component,
391
                    'callback' => $callback,
392
                    'contextid' => $contextid,
393
                    'args' => $args
394
                )
395
        );
396
 
397
        // Reformat arguments into something less unwieldy.
398
        $arguments = array();
399
        foreach ($params['args'] as $paramargument) {
400
            $arguments[$paramargument['name']] = $paramargument['value'];
401
        }
402
 
403
        $context = context::instance_by_id($contextid);
404
        self::validate_context($context);
405
        $arguments['context'] = $context;
406
 
407
        // Hack alert: Set a default URL to stop the annoying debug.
408
        $PAGE->set_url('/');
409
        // Hack alert: Forcing bootstrap_renderer to initiate moodle page.
410
        $OUTPUT->header();
411
 
412
        // Overwriting page_requirements_manager with the fragment one so only JS included from
413
        // this point is returned to the user.
414
        $PAGE->start_collecting_javascript_requirements();
415
        $data = component_callback($params['component'], 'output_fragment_' . $params['callback'], array($arguments));
416
        $jsfooter = $PAGE->requires->get_end_code();
417
        $output = array('html' => $data, 'javascript' => $jsfooter);
418
        return $output;
419
    }
420
 
421
    /**
422
     * Returns description of get_fragment() result value
423
     *
424
     * @return \core_external\external_description
425
     * @since Moodle 3.1
426
     */
427
    public static function get_fragment_returns() {
428
        return new external_single_structure(
429
            array(
430
                'html' => new external_value(PARAM_RAW, 'HTML fragment.'),
431
                'javascript' => new external_value(PARAM_RAW, 'JavaScript fragment')
432
            )
433
        );
434
    }
435
 
436
    /**
437
     * Parameters for function update_inplace_editable()
438
     *
439
     * @since Moodle 3.1
440
     * @return external_function_parameters
441
     */
442
    public static function update_inplace_editable_parameters() {
443
        return new external_function_parameters(
444
            array(
445
                'component' => new external_value(PARAM_COMPONENT, 'component responsible for the update', VALUE_REQUIRED),
446
                'itemtype' => new external_value(PARAM_NOTAGS, 'type of the updated item inside the component', VALUE_REQUIRED),
447
                'itemid' => new external_value(PARAM_RAW, 'identifier of the updated item', VALUE_REQUIRED),
448
                'value' => new external_value(PARAM_RAW, 'new value', VALUE_REQUIRED),
449
            ));
450
    }
451
 
452
    /**
453
     * Update any component's editable value assuming that component implements necessary callback
454
     *
455
     * @since Moodle 3.1
456
     * @param string $component
457
     * @param string $itemtype
458
     * @param string $itemid
459
     * @param string $value
460
     */
461
    public static function update_inplace_editable($component, $itemtype, $itemid, $value) {
462
        global $PAGE;
463
        // Validate and normalize parameters.
464
        $params = self::validate_parameters(self::update_inplace_editable_parameters(),
465
                      array('component' => $component, 'itemtype' => $itemtype, 'itemid' => $itemid, 'value' => $value));
466
        if (!$functionname = component_callback_exists($component, 'inplace_editable')) {
467
            throw new \moodle_exception('inplaceeditableerror');
468
        }
469
        $tmpl = component_callback($params['component'], 'inplace_editable',
470
            array($params['itemtype'], $params['itemid'], $params['value']));
471
        if (!$tmpl || !($tmpl instanceof \core\output\inplace_editable)) {
472
            throw new \moodle_exception('inplaceeditableerror');
473
        }
474
        return $tmpl->export_for_template($PAGE->get_renderer('core'));
475
    }
476
 
477
    /**
478
     * Return structure for update_inplace_editable()
479
     *
480
     * @since Moodle 3.1
481
     * @return \core_external\external_description
482
     */
483
    public static function update_inplace_editable_returns() {
484
        return new external_single_structure(
485
            array(
486
                'displayvalue' => new external_value(PARAM_RAW, 'display value (may contain link or other html tags)'),
487
                'component' => new external_value(PARAM_NOTAGS, 'component responsible for the update', VALUE_OPTIONAL),
488
                'itemtype' => new external_value(PARAM_NOTAGS, 'itemtype', VALUE_OPTIONAL),
489
                'value' => new external_value(PARAM_RAW, 'value of the item as it is stored', VALUE_OPTIONAL),
490
                'itemid' => new external_value(PARAM_RAW, 'identifier of the updated item', VALUE_OPTIONAL),
491
                'edithint' => new external_value(PARAM_NOTAGS, 'hint for editing element', VALUE_OPTIONAL),
492
                'editlabel' => new external_value(PARAM_RAW, 'label for editing element', VALUE_OPTIONAL),
493
                'editicon' => new external_single_structure([
494
                    'key' => new external_value(PARAM_RAW, 'Edit icon key', VALUE_OPTIONAL),
495
                    'component' => new external_value(PARAM_COMPONENT, 'Edit icon component', VALUE_OPTIONAL),
496
                    'title' => new external_value(PARAM_NOTAGS, 'Edit icon title', VALUE_OPTIONAL),
497
                ], 'Edit icon', VALUE_OPTIONAL),
498
                'type' => new external_value(PARAM_ALPHA, 'type of the element (text, toggle, select)', VALUE_OPTIONAL),
499
                'options' => new external_value(PARAM_RAW, 'options of the element, format depends on type', VALUE_OPTIONAL),
500
                'linkeverything' => new external_value(PARAM_INT, 'Should everything be wrapped in the edit link or link displayed separately', VALUE_OPTIONAL),
501
            )
502
        );
503
    }
504
 
505
    /**
506
     * Returns description of fetch_notifications() parameters.
507
     *
508
     * @return external_function_parameters
509
     * @since Moodle 3.1
510
     */
511
    public static function fetch_notifications_parameters() {
512
        return new external_function_parameters(
513
            array(
514
                'contextid' => new external_value(PARAM_INT, 'Context ID', VALUE_REQUIRED),
515
            ));
516
    }
517
 
518
    /**
519
     * Returns description of fetch_notifications() result value.
520
     *
521
     * @return \core_external\external_description
522
     * @since Moodle 3.1
523
     */
524
    public static function fetch_notifications_returns() {
525
        return new external_multiple_structure(
526
            new external_single_structure(
527
                array(
528
                    'template'      => new external_value(PARAM_RAW, 'Name of the template'),
529
                    'variables'     => new external_single_structure(array(
530
                        'message'       => new external_value(PARAM_RAW, 'HTML content of the Notification'),
531
                        'extraclasses'  => new external_value(PARAM_RAW, 'Extra classes to provide to the tmeplate'),
532
                        'announce'      => new external_value(PARAM_RAW, 'Whether to announce'),
533
                        'closebutton'   => new external_value(PARAM_RAW, 'Whether to close'),
534
                    )),
535
                )
536
            )
537
        );
538
    }
539
 
540
    /**
541
     * Returns the list of notifications against the current session.
542
     *
543
     * @return array
544
     * @since Moodle 3.1
545
     */
546
    public static function fetch_notifications($contextid) {
547
        global $PAGE;
548
 
549
        self::validate_parameters(self::fetch_notifications_parameters(), [
550
                'contextid' => $contextid,
551
            ]);
552
 
553
        $context = \context::instance_by_id($contextid);
554
        self::validate_context($context);
555
 
556
        return \core\notification::fetch_as_array($PAGE->get_renderer('core'));
557
    }
558
}