Proyectos de Subversion Moodle

Rev

Rev 1 | Mostrar el archivo completo | | | Autoría | Ultima modificación | Ver Log |

Rev 1 Rev 1441
Línea 28... Línea 28...
28
 * @subpackage lib
28
 * @subpackage lib
29
 * @copyright  1999 onwards Martin Dougiamas {@link http://moodle.com}
29
 * @copyright  1999 onwards Martin Dougiamas {@link http://moodle.com}
30
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
30
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
31
 */
31
 */
Línea 32... Línea -...
32
 
-
 
33
use Psr\Http\Message\UriInterface;
-
 
34
 
32
 
Línea 35... Línea 33...
35
defined('MOODLE_INTERNAL') || die();
33
defined('MOODLE_INTERNAL') || die();
Línea 36... Línea 34...
36
 
34
 
Línea 241... Línea 239...
241
        return '';
239
        return '';
242
    }
240
    }
243
}
241
}
Línea 244... Línea 242...
244
 
242
 
245
/**
-
 
246
 * Class for creating and manipulating urls.
-
 
247
 *
-
 
248
 * It can be used in moodle pages where config.php has been included without any further includes.
-
 
249
 *
-
 
250
 * It is useful for manipulating urls with long lists of params.
-
 
251
 * One situation where it will be useful is a page which links to itself to perform various actions
-
 
252
 * and / or to process form data. A moodle_url object :
-
 
253
 * can be created for a page to refer to itself with all the proper get params being passed from page call to
-
 
254
 * page call and methods can be used to output a url including all the params, optionally adding and overriding
-
 
255
 * params and can also be used to
-
 
256
 *     - output the url without any get params
-
 
257
 *     - and output the params as hidden fields to be output within a form
-
 
258
 *
-
 
259
 * @copyright 2007 jamiesensei
-
 
260
 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
-
 
261
 * @package core
-
 
262
 */
-
 
263
class moodle_url {
-
 
264
 
-
 
265
    /**
-
 
266
     * Scheme, ex.: http, https
-
 
267
     * @var string
-
 
268
     */
-
 
269
    protected $scheme = '';
-
 
270
 
-
 
271
    /**
-
 
272
     * Hostname.
-
 
273
     * @var string
-
 
274
     */
-
 
275
    protected $host = '';
-
 
276
 
-
 
277
    /**
-
 
278
     * Port number, empty means default 80 or 443 in case of http.
-
 
279
     * @var int
-
 
280
     */
-
 
281
    protected $port = '';
-
 
282
 
-
 
283
    /**
-
 
284
     * Username for http auth.
-
 
285
     * @var string
-
 
286
     */
-
 
287
    protected $user = '';
-
 
288
 
-
 
289
    /**
-
 
290
     * Password for http auth.
-
 
291
     * @var string
-
 
292
     */
-
 
293
    protected $pass = '';
-
 
294
 
-
 
295
    /**
-
 
296
     * Script path.
-
 
297
     * @var string
-
 
298
     */
-
 
299
    protected $path = '';
-
 
300
 
-
 
301
    /**
-
 
302
     * Optional slash argument value.
-
 
303
     * @var string
-
 
304
     */
-
 
305
    protected $slashargument = '';
-
 
306
 
-
 
307
    /**
-
 
308
     * Anchor, may be also empty, null means none.
-
 
309
     * @var string
-
 
310
     */
-
 
311
    protected $anchor = null;
-
 
312
 
-
 
313
    /**
-
 
314
     * Url parameters as associative array.
-
 
315
     * @var array
-
 
316
     */
-
 
317
    protected $params = array();
-
 
318
 
-
 
319
    /**
-
 
320
     * Create new instance of moodle_url.
-
 
321
     *
-
 
322
     * @param moodle_url|string $url - moodle_url means make a copy of another
-
 
323
     *      moodle_url and change parameters, string means full url or shortened
-
 
324
     *      form (ex.: '/course/view.php'). It is strongly encouraged to not include
-
 
325
     *      query string because it may result in double encoded values. Use the
-
 
326
     *      $params instead. For admin URLs, just use /admin/script.php, this
-
 
327
     *      class takes care of the $CFG->admin issue.
-
 
328
     * @param array $params these params override current params or add new
-
 
329
     * @param string $anchor The anchor to use as part of the URL if there is one.
-
 
330
     * @throws moodle_exception
-
 
331
     */
-
 
332
    public function __construct($url, array $params = null, $anchor = null) {
-
 
333
        global $CFG;
-
 
334
 
-
 
335
        if ($url instanceof moodle_url) {
-
 
336
            $this->scheme = $url->scheme;
-
 
337
            $this->host = $url->host;
-
 
338
            $this->port = $url->port;
-
 
339
            $this->user = $url->user;
-
 
340
            $this->pass = $url->pass;
-
 
341
            $this->path = $url->path;
-
 
342
            $this->slashargument = $url->slashargument;
-
 
343
            $this->params = $url->params;
-
 
344
            $this->anchor = $url->anchor;
-
 
345
 
-
 
346
        } else {
-
 
347
            $url = $url ?? '';
-
 
348
            // Detect if anchor used.
-
 
349
            $apos = strpos($url, '#');
-
 
350
            if ($apos !== false) {
-
 
351
                $anchor = substr($url, $apos);
-
 
352
                $anchor = ltrim($anchor, '#');
-
 
353
                $this->set_anchor($anchor);
-
 
354
                $url = substr($url, 0, $apos);
-
 
355
            }
-
 
356
 
-
 
357
            // Normalise shortened form of our url ex.: '/course/view.php'.
-
 
358
            if (strpos($url, '/') === 0) {
-
 
359
                $url = $CFG->wwwroot.$url;
-
 
360
            }
-
 
361
 
-
 
362
            if ($CFG->admin !== 'admin') {
-
 
363
                if (strpos($url, "$CFG->wwwroot/admin/") === 0) {
-
 
364
                    $url = str_replace("$CFG->wwwroot/admin/", "$CFG->wwwroot/$CFG->admin/", $url);
-
 
365
                }
-
 
366
            }
-
 
367
 
-
 
368
            // Parse the $url.
-
 
369
            $parts = parse_url($url);
-
 
370
            if ($parts === false) {
-
 
371
                throw new moodle_exception('invalidurl');
-
 
372
            }
-
 
373
            if (isset($parts['query'])) {
-
 
374
                // Note: the values may not be correctly decoded, url parameters should be always passed as array.
-
 
375
                parse_str(str_replace('&', '&', $parts['query']), $this->params);
-
 
376
            }
-
 
377
            unset($parts['query']);
-
 
378
            foreach ($parts as $key => $value) {
-
 
379
                $this->$key = $value;
-
 
380
            }
-
 
381
 
-
 
382
            // Detect slashargument value from path - we do not support directory names ending with .php.
-
 
383
            $pos = strpos($this->path, '.php/');
-
 
384
            if ($pos !== false) {
-
 
385
                $this->slashargument = substr($this->path, $pos + 4);
-
 
386
                $this->path = substr($this->path, 0, $pos + 4);
-
 
387
            }
-
 
388
        }
-
 
389
 
-
 
390
        $this->params($params);
-
 
391
        if ($anchor !== null) {
-
 
392
            $this->anchor = (string)$anchor;
-
 
393
        }
-
 
394
    }
-
 
395
 
-
 
396
    /**
-
 
397
     * Add an array of params to the params for this url.
-
 
398
     *
-
 
399
     * The added params override existing ones if they have the same name.
-
 
400
     *
-
 
401
     * @param array $params Defaults to null. If null then returns all params.
-
 
402
     * @return array Array of Params for url.
-
 
403
     * @throws coding_exception
-
 
404
     */
-
 
405
    public function params(array $params = null) {
-
 
406
        $params = (array)$params;
-
 
407
 
-
 
408
        foreach ($params as $key => $value) {
-
 
409
            if (is_int($key)) {
-
 
410
                throw new coding_exception('Url parameters can not have numeric keys!');
-
 
411
            }
-
 
412
            if (!is_string($value)) {
-
 
413
                if (is_array($value)) {
-
 
414
                    throw new coding_exception('Url parameters values can not be arrays!');
-
 
415
                }
-
 
416
                if (is_object($value) and !method_exists($value, '__toString')) {
-
 
417
                    throw new coding_exception('Url parameters values can not be objects, unless __toString() is defined!');
-
 
418
                }
-
 
419
            }
-
 
420
            $this->params[$key] = (string)$value;
-
 
421
        }
-
 
422
        return $this->params;
-
 
423
    }
-
 
424
 
-
 
425
    /**
-
 
426
     * Remove all params if no arguments passed.
-
 
427
     * Remove selected params if arguments are passed.
-
 
428
     *
-
 
429
     * Can be called as either remove_params('param1', 'param2')
-
 
430
     * or remove_params(array('param1', 'param2')).
-
 
431
     *
-
 
432
     * @param string[]|string $params,... either an array of param names, or 1..n string params to remove as args.
-
 
433
     * @return array url parameters
-
 
434
     */
-
 
435
    public function remove_params($params = null) {
-
 
436
        if (!is_array($params)) {
-
 
437
            $params = func_get_args();
-
 
438
        }
-
 
439
        foreach ($params as $param) {
-
 
440
            unset($this->params[$param]);
-
 
441
        }
-
 
442
        return $this->params;
-
 
443
    }
-
 
444
 
-
 
445
    /**
-
 
446
     * Remove all url parameters.
-
 
447
     *
-
 
448
     * @todo remove the unused param.
-
 
449
     * @param array $params Unused param
-
 
450
     * @return void
-
 
451
     */
-
 
452
    public function remove_all_params($params = null) {
-
 
453
        $this->params = array();
-
 
454
        $this->slashargument = '';
-
 
455
    }
-
 
456
 
-
 
457
    /**
-
 
458
     * Add a param to the params for this url.
-
 
459
     *
-
 
460
     * The added param overrides existing one if they have the same name.
-
 
461
     *
-
 
462
     * @param string $paramname name
-
 
463
     * @param string $newvalue Param value. If new value specified current value is overriden or parameter is added
-
 
464
     * @return mixed string parameter value, null if parameter does not exist
-
 
465
     */
-
 
466
    public function param($paramname, $newvalue = '') {
-
 
467
        if (func_num_args() > 1) {
-
 
468
            // Set new value.
-
 
469
            $this->params(array($paramname => $newvalue));
-
 
470
        }
-
 
471
        if (isset($this->params[$paramname])) {
-
 
472
            return $this->params[$paramname];
-
 
473
        } else {
-
 
474
            return null;
-
 
475
        }
-
 
476
    }
-
 
477
 
-
 
478
    /**
-
 
479
     * Merges parameters and validates them
-
 
480
     *
-
 
481
     * @param array $overrideparams
-
 
482
     * @return array merged parameters
-
 
483
     * @throws coding_exception
-
 
484
     */
-
 
485
    protected function merge_overrideparams(array $overrideparams = null) {
-
 
486
        $overrideparams = (array)$overrideparams;
-
 
487
        $params = $this->params;
-
 
488
        foreach ($overrideparams as $key => $value) {
-
 
489
            if (is_int($key)) {
-
 
490
                throw new coding_exception('Overridden parameters can not have numeric keys!');
-
 
491
            }
-
 
492
            if (is_array($value)) {
-
 
493
                throw new coding_exception('Overridden parameters values can not be arrays!');
-
 
494
            }
-
 
495
            if (is_object($value) and !method_exists($value, '__toString')) {
-
 
496
                throw new coding_exception('Overridden parameters values can not be objects, unless __toString() is defined!');
-
 
497
            }
-
 
498
            $params[$key] = (string)$value;
-
 
499
        }
-
 
500
        return $params;
-
 
501
    }
-
 
502
 
-
 
503
    /**
-
 
504
     * Get the params as as a query string.
-
 
505
     *
-
 
506
     * This method should not be used outside of this method.
-
 
507
     *
-
 
508
     * @param bool $escaped Use & as params separator instead of plain &
-
 
509
     * @param array $overrideparams params to add to the output params, these
-
 
510
     *      override existing ones with the same name.
-
 
511
     * @return string query string that can be added to a url.
-
 
512
     */
-
 
513
    public function get_query_string($escaped = true, array $overrideparams = null) {
-
 
514
        $arr = array();
-
 
515
        if ($overrideparams !== null) {
-
 
516
            $params = $this->merge_overrideparams($overrideparams);
-
 
517
        } else {
-
 
518
            $params = $this->params;
-
 
519
        }
-
 
520
        foreach ($params as $key => $val) {
-
 
521
            if (is_array($val)) {
-
 
522
                foreach ($val as $index => $value) {
-
 
523
                    $arr[] = rawurlencode($key.'['.$index.']')."=".rawurlencode($value);
-
 
524
                }
-
 
525
            } else {
-
 
526
                if (isset($val) && $val !== '') {
-
 
527
                    $arr[] = rawurlencode($key)."=".rawurlencode($val);
-
 
528
                } else {
-
 
529
                    $arr[] = rawurlencode($key);
-
 
530
                }
-
 
531
            }
-
 
532
        }
-
 
533
        if ($escaped) {
-
 
534
            return implode('&', $arr);
-
 
535
        } else {
-
 
536
            return implode('&', $arr);
-
 
537
        }
-
 
538
    }
-
 
539
 
-
 
540
    /**
-
 
541
     * Get the url params as an array of key => value pairs.
-
 
542
     *
-
 
543
     * This helps in handling cases where url params contain arrays.
-
 
544
     *
-
 
545
     * @return array params array for templates.
-
 
546
     */
-
 
547
    public function export_params_for_template(): array {
-
 
548
        $data = [];
-
 
549
        foreach ($this->params as $key => $val) {
-
 
550
            if (is_array($val)) {
-
 
551
                foreach ($val as $index => $value) {
-
 
552
                    $data[] = ['name' => $key.'['.$index.']', 'value' => $value];
-
 
553
                }
-
 
554
            } else {
-
 
555
                $data[] = ['name' => $key, 'value' => $val];
-
 
556
            }
-
 
557
        }
-
 
558
        return $data;
-
 
559
    }
-
 
560
 
-
 
561
    /**
-
 
562
     * Shortcut for printing of encoded URL.
-
 
563
     *
-
 
564
     * @return string
-
 
565
     */
-
 
566
    public function __toString() {
-
 
567
        return $this->out(true);
-
 
568
    }
-
 
569
 
-
 
570
    /**
-
 
571
     * Output url.
-
 
572
     *
-
 
573
     * If you use the returned URL in HTML code, you want the escaped ampersands. If you use
-
 
574
     * the returned URL in HTTP headers, you want $escaped=false.
-
 
575
     *
-
 
576
     * @param bool $escaped Use & as params separator instead of plain &
-
 
577
     * @param array $overrideparams params to add to the output url, these override existing ones with the same name.
-
 
578
     * @return string Resulting URL
-
 
579
     */
-
 
580
    public function out($escaped = true, array $overrideparams = null) {
-
 
581
 
-
 
582
        global $CFG;
-
 
583
 
-
 
584
        if (!is_bool($escaped)) {
-
 
585
            debugging('Escape parameter must be of type boolean, '.gettype($escaped).' given instead.');
-
 
586
        }
-
 
587
 
-
 
588
        $url = $this;
-
 
589
 
-
 
590
        // Allow url's to be rewritten by a plugin.
-
 
591
        if (isset($CFG->urlrewriteclass) && !isset($CFG->upgraderunning)) {
-
 
592
            $class = $CFG->urlrewriteclass;
-
 
593
            $pluginurl = $class::url_rewrite($url);
-
 
594
            if ($pluginurl instanceof moodle_url) {
-
 
595
                $url = $pluginurl;
-
 
596
            }
-
 
597
        }
-
 
598
 
-
 
599
        return $url->raw_out($escaped, $overrideparams);
-
 
600
 
-
 
601
    }
-
 
602
 
-
 
603
    /**
-
 
604
     * Output url without any rewrites
-
 
605
     *
-
 
606
     * This is identical in signature and use to out() but doesn't call the rewrite handler.
-
 
607
     *
-
 
608
     * @param bool $escaped Use & as params separator instead of plain &
-
 
609
     * @param array $overrideparams params to add to the output url, these override existing ones with the same name.
-
 
610
     * @return string Resulting URL
-
 
611
     */
-
 
612
    public function raw_out($escaped = true, array $overrideparams = null) {
-
 
613
        if (!is_bool($escaped)) {
-
 
614
            debugging('Escape parameter must be of type boolean, '.gettype($escaped).' given instead.');
-
 
615
        }
-
 
616
 
-
 
617
        $uri = $this->out_omit_querystring().$this->slashargument;
-
 
618
 
-
 
619
        $querystring = $this->get_query_string($escaped, $overrideparams);
-
 
620
        if ($querystring !== '') {
-
 
621
            $uri .= '?' . $querystring;
-
 
622
        }
-
 
623
 
-
 
624
        $uri .= $this->get_encoded_anchor();
-
 
625
 
-
 
626
        return $uri;
-
 
627
    }
-
 
628
 
-
 
629
    /**
-
 
630
     * Encode the anchor according to RFC 3986.
-
 
631
     *
-
 
632
     * @return string The encoded anchor
-
 
633
     */
-
 
634
    public function get_encoded_anchor(): string {
-
 
635
        if (is_null($this->anchor)) {
-
 
636
            return '';
-
 
637
        }
-
 
638
 
-
 
639
        // RFC 3986 allows the following characters in a fragment without them being encoded:
-
 
640
        // pct-encoded: "%" HEXDIG HEXDIG
-
 
641
        // unreserved:  ALPHA / DIGIT / "-" / "." / "_" / "~" /
-
 
642
        // sub-delims:  "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "=" / ":" / "@"
-
 
643
        // fragment:    "/" / "?"
-
 
644
        //
-
 
645
        // All other characters should be encoded.
-
 
646
        // These should not be encoded in the fragment unless they were already encoded.
-
 
647
 
-
 
648
        // The following characters are allowed in the fragment without encoding.
-
 
649
        // In addition to this list is pct-encoded, but we can't easily handle this with a regular expression.
-
 
650
        $allowed = 'a-zA-Z0-9\\-._~!$&\'()*+,;=:@\/?';
-
 
651
        $anchor = '#';
-
 
652
 
-
 
653
        $remainder = $this->anchor;
-
 
654
        do {
-
 
655
            // Split the string on any %.
-
 
656
            $parts = explode('%', $remainder, 2);
-
 
657
            $anchorparts = array_shift($parts);
-
 
658
 
-
 
659
            // The first part can go through our preg_replace_callback to quote any relevant characters.
-
 
660
            $anchor .= preg_replace_callback(
-
 
661
                '/[^' . $allowed . ']/',
-
 
662
                fn ($matches) => rawurlencode($matches[0]),
-
 
663
                $anchorparts,
-
 
664
            );
-
 
665
 
-
 
666
            // The second part _might_ be a valid pct-encoded character.
-
 
667
            if (count($parts) === 0) {
-
 
668
                break;
-
 
669
            }
-
 
670
 
-
 
671
            // If the second part is a valid pct-encoded character, append it to the anchor.
-
 
672
            $remainder = array_shift($parts);
-
 
673
            if (preg_match('/^[a-fA-F0-9]{2}/', $remainder, $matches)) {
-
 
674
                $anchor .= "%{$matches[0]}";
-
 
675
                $remainder = substr($remainder, 2);
-
 
676
            } else {
-
 
677
                // This was not a valid pct-encoded character. Encode the % and continue with the next part.
-
 
678
                $anchor .= rawurlencode('%');
-
 
679
            }
-
 
680
        } while (strlen($remainder) > 0);
-
 
681
 
-
 
682
        return $anchor;
-
 
683
    }
-
 
684
 
-
 
685
    /**
-
 
686
     * Returns url without parameters, everything before '?'.
-
 
687
     *
-
 
688
     * @param bool $includeanchor if {@link self::anchor} is defined, should it be returned?
-
 
689
     * @return string
-
 
690
     */
-
 
691
    public function out_omit_querystring($includeanchor = false) {
-
 
692
 
-
 
693
        $uri = $this->scheme ? $this->scheme.':'.((strtolower($this->scheme) == 'mailto') ? '':'//'): '';
-
 
694
        $uri .= $this->user ? $this->user.($this->pass? ':'.$this->pass:'').'@':'';
-
 
695
        $uri .= $this->host ? $this->host : '';
-
 
696
        $uri .= $this->port ? ':'.$this->port : '';
-
 
697
        $uri .= $this->path ? $this->path : '';
-
 
698
        if ($includeanchor) {
-
 
699
            $uri .= $this->get_encoded_anchor();
-
 
700
        }
-
 
701
 
-
 
702
        return $uri;
-
 
703
    }
-
 
704
 
-
 
705
    /**
-
 
706
     * Compares this moodle_url with another.
-
 
707
     *
-
 
708
     * See documentation of constants for an explanation of the comparison flags.
-
 
709
     *
-
 
710
     * @param moodle_url $url The moodle_url object to compare
-
 
711
     * @param int $matchtype The type of comparison (URL_MATCH_BASE, URL_MATCH_PARAMS, URL_MATCH_EXACT)
-
 
712
     * @return bool
-
 
713
     */
-
 
714
    public function compare(moodle_url $url, $matchtype = URL_MATCH_EXACT) {
-
 
715
 
-
 
716
        $baseself = $this->out_omit_querystring();
-
 
717
        $baseother = $url->out_omit_querystring();
-
 
718
 
-
 
719
        // Append index.php if there is no specific file.
-
 
720
        if (substr($baseself, -1) == '/') {
-
 
721
            $baseself .= 'index.php';
-
 
722
        }
-
 
723
        if (substr($baseother, -1) == '/') {
-
 
724
            $baseother .= 'index.php';
-
 
725
        }
-
 
726
 
-
 
727
        // Compare the two base URLs.
-
 
728
        if ($baseself != $baseother) {
-
 
729
            return false;
-
 
730
        }
-
 
731
 
-
 
732
        if ($matchtype == URL_MATCH_BASE) {
-
 
733
            return true;
-
 
734
        }
-
 
735
 
-
 
736
        $urlparams = $url->params();
-
 
737
        foreach ($this->params() as $param => $value) {
-
 
738
            if ($param == 'sesskey') {
-
 
739
                continue;
-
 
740
            }
-
 
741
            if (!array_key_exists($param, $urlparams) || $urlparams[$param] != $value) {
-
 
742
                return false;
-
 
743
            }
-
 
744
        }
-
 
745
 
-
 
746
        if ($matchtype == URL_MATCH_PARAMS) {
-
 
747
            return true;
-
 
748
        }
-
 
749
 
-
 
750
        foreach ($urlparams as $param => $value) {
-
 
751
            if ($param == 'sesskey') {
-
 
752
                continue;
-
 
753
            }
-
 
754
            if (!array_key_exists($param, $this->params()) || $this->param($param) != $value) {
-
 
755
                return false;
-
 
756
            }
-
 
757
        }
-
 
758
 
-
 
759
        if ($url->anchor !== $this->anchor) {
-
 
760
            return false;
-
 
761
        }
-
 
762
 
-
 
763
        return true;
-
 
764
    }
-
 
765
 
-
 
766
    /**
-
 
767
     * Sets the anchor for the URI (the bit after the hash)
-
 
768
     *
-
 
769
     * @param string $anchor null means remove previous
-
 
770
     */
-
 
771
    public function set_anchor($anchor) {
-
 
772
        if (is_null($anchor)) {
-
 
773
            // Remove.
-
 
774
            $this->anchor = null;
-
 
775
        } else {
-
 
776
            $this->anchor = $anchor;
-
 
777
        }
-
 
778
    }
-
 
779
 
-
 
780
    /**
-
 
781
     * Sets the scheme for the URI (the bit before ://)
-
 
782
     *
-
 
783
     * @param string $scheme
-
 
784
     */
-
 
785
    public function set_scheme($scheme) {
-
 
786
        // See http://www.ietf.org/rfc/rfc3986.txt part 3.1.
-
 
787
        if (preg_match('/^[a-zA-Z][a-zA-Z0-9+.-]*$/', $scheme)) {
-
 
788
            $this->scheme = $scheme;
-
 
789
        } else {
-
 
790
            throw new coding_exception('Bad URL scheme.');
-
 
791
        }
-
 
792
    }
-
 
793
 
-
 
794
    /**
-
 
795
     * Sets the url slashargument value.
-
 
796
     *
-
 
797
     * @param string $path usually file path
-
 
798
     * @param string $parameter name of page parameter if slasharguments not supported
-
 
799
     * @param bool $supported usually null, then it depends on $CFG->slasharguments, use true or false for other servers
-
 
800
     * @return void
-
 
801
     */
-
 
802
    public function set_slashargument($path, $parameter = 'file', $supported = null) {
-
 
803
        global $CFG;
-
 
804
        if (is_null($supported)) {
-
 
805
            $supported = !empty($CFG->slasharguments);
-
 
806
        }
-
 
807
 
-
 
808
        if ($supported) {
-
 
809
            $parts = explode('/', $path);
-
 
810
            $parts = array_map('rawurlencode', $parts);
-
 
811
            $path  = implode('/', $parts);
-
 
812
            $this->slashargument = $path;
-
 
813
            unset($this->params[$parameter]);
-
 
814
 
-
 
815
        } else {
-
 
816
            $this->slashargument = '';
-
 
817
            $this->params[$parameter] = $path;
-
 
818
        }
-
 
819
    }
-
 
820
 
-
 
821
    // Static factory methods.
-
 
822
 
-
 
823
    /**
-
 
824
     * Create a new moodle_url instance from a UriInterface.
-
 
825
     *
-
 
826
     * @param UriInterface $uri
-
 
827
     * @return self
-
 
828
     */
-
 
829
    public static function from_uri(UriInterface $uri): self {
-
 
830
        $url = new self(
-
 
831
            url: $uri->getScheme() . '://' . $uri->getAuthority() . $uri->getPath(),
-
 
832
            anchor: $uri->getFragment() ?: null,
-
 
833
        );
-
 
834
 
-
 
835
        $params = $uri->getQuery();
-
 
836
        foreach (explode('&', $params) as $param) {
-
 
837
            $url->param(...explode('=', $param, 2));
-
 
838
        }
-
 
839
 
-
 
840
        return $url;
-
 
841
    }
-
 
842
 
-
 
843
    /**
-
 
844
     * General moodle file url.
-
 
845
     *
-
 
846
     * @param string $urlbase the script serving the file
-
 
847
     * @param string $path
-
 
848
     * @param bool $forcedownload
-
 
849
     * @return moodle_url
-
 
850
     */
-
 
851
    public static function make_file_url($urlbase, $path, $forcedownload = false) {
-
 
852
        $params = array();
-
 
853
        if ($forcedownload) {
-
 
854
            $params['forcedownload'] = 1;
-
 
855
        }
-
 
856
        $url = new moodle_url($urlbase, $params);
-
 
857
        $url->set_slashargument($path);
-
 
858
        return $url;
-
 
859
    }
-
 
860
 
-
 
861
    /**
-
 
862
     * Factory method for creation of url pointing to plugin file.
-
 
863
     *
-
 
864
     * Please note this method can be used only from the plugins to
-
 
865
     * create urls of own files, it must not be used outside of plugins!
-
 
866
     *
-
 
867
     * @param int $contextid
-
 
868
     * @param string $component
-
 
869
     * @param string $area
-
 
870
     * @param ?int $itemid
-
 
871
     * @param string $pathname
-
 
872
     * @param string $filename
-
 
873
     * @param bool $forcedownload
-
 
874
     * @param mixed $includetoken Whether to use a user token when displaying this group image.
-
 
875
     *                True indicates to generate a token for current user, and integer value indicates to generate a token for the
-
 
876
     *                user whose id is the value indicated.
-
 
877
     *                If the group picture is included in an e-mail or some other location where the audience is a specific
-
 
878
     *                user who will not be logged in when viewing, then we use a token to authenticate the user.
-
 
879
     * @return moodle_url
-
 
880
     */
-
 
881
    public static function make_pluginfile_url($contextid, $component, $area, $itemid, $pathname, $filename,
-
 
882
                                               $forcedownload = false, $includetoken = false) {
-
 
883
        global $CFG, $USER;
-
 
884
 
-
 
885
        $path = [];
-
 
886
 
-
 
887
        if ($includetoken) {
-
 
888
            $urlbase = "$CFG->wwwroot/tokenpluginfile.php";
-
 
889
            $userid = $includetoken === true ? $USER->id : $includetoken;
-
 
890
            $token = get_user_key('core_files', $userid);
-
 
891
            if ($CFG->slasharguments) {
-
 
892
                $path[] = $token;
-
 
893
            }
-
 
894
        } else {
-
 
895
            $urlbase = "$CFG->wwwroot/pluginfile.php";
-
 
896
        }
-
 
897
        $path[] = $contextid;
-
 
898
        $path[] = $component;
-
 
899
        $path[] = $area;
-
 
900
 
-
 
901
        if ($itemid !== null) {
-
 
902
            $path[] = $itemid;
-
 
903
        }
-
 
904
 
-
 
905
        $path = "/" . implode('/', $path) . "{$pathname}{$filename}";
-
 
906
 
-
 
907
        $url = self::make_file_url($urlbase, $path, $forcedownload, $includetoken);
-
 
908
        if ($includetoken && empty($CFG->slasharguments)) {
-
 
909
            $url->param('token', $token);
-
 
910
        }
-
 
911
        return $url;
-
 
912
    }
-
 
913
 
-
 
914
    /**
-
 
915
     * Factory method for creation of url pointing to plugin file.
-
 
916
     * This method is the same that make_pluginfile_url but pointing to the webservice pluginfile.php script.
-
 
917
     * It should be used only in external functions.
-
 
918
     *
-
 
919
     * @since  2.8
-
 
920
     * @param int $contextid
-
 
921
     * @param string $component
-
 
922
     * @param string $area
-
 
923
     * @param int $itemid
-
 
924
     * @param string $pathname
-
 
925
     * @param string $filename
-
 
926
     * @param bool $forcedownload
-
 
927
     * @return moodle_url
-
 
928
     */
-
 
929
    public static function make_webservice_pluginfile_url($contextid, $component, $area, $itemid, $pathname, $filename,
-
 
930
                                               $forcedownload = false) {
-
 
931
        global $CFG;
-
 
932
        $urlbase = "$CFG->wwwroot/webservice/pluginfile.php";
-
 
933
        if ($itemid === null) {
-
 
934
            return self::make_file_url($urlbase, "/$contextid/$component/$area".$pathname.$filename, $forcedownload);
-
 
935
        } else {
-
 
936
            return self::make_file_url($urlbase, "/$contextid/$component/$area/$itemid".$pathname.$filename, $forcedownload);
-
 
937
        }
-
 
938
    }
-
 
939
 
-
 
940
    /**
-
 
941
     * Factory method for creation of url pointing to draft file of current user.
-
 
942
     *
-
 
943
     * @param int $draftid draft item id
-
 
944
     * @param string $pathname
-
 
945
     * @param string $filename
-
 
946
     * @param bool $forcedownload
-
 
947
     * @return moodle_url
-
 
948
     */
-
 
949
    public static function make_draftfile_url($draftid, $pathname, $filename, $forcedownload = false) {
-
 
950
        global $CFG, $USER;
-
 
951
        $urlbase = "$CFG->wwwroot/draftfile.php";
-
 
952
        $context = context_user::instance($USER->id);
-
 
953
 
-
 
954
        return self::make_file_url($urlbase, "/$context->id/user/draft/$draftid".$pathname.$filename, $forcedownload);
-
 
955
    }
-
 
956
 
-
 
957
    /**
-
 
958
     * Factory method for creating of links to legacy course files.
-
 
959
     *
-
 
960
     * @param int $courseid
-
 
961
     * @param string $filepath
-
 
962
     * @param bool $forcedownload
-
 
963
     * @return moodle_url
-
 
964
     */
-
 
965
    public static function make_legacyfile_url($courseid, $filepath, $forcedownload = false) {
-
 
966
        global $CFG;
-
 
967
 
-
 
968
        $urlbase = "$CFG->wwwroot/file.php";
-
 
969
        return self::make_file_url($urlbase, '/'.$courseid.'/'.$filepath, $forcedownload);
-
 
970
    }
-
 
971
 
-
 
972
    /**
-
 
973
     * Checks if URL is relative to $CFG->wwwroot.
-
 
974
     *
-
 
975
     * @return bool True if URL is relative to $CFG->wwwroot; otherwise, false.
-
 
976
     */
-
 
977
    public function is_local_url(): bool {
-
 
978
        global $CFG;
-
 
979
 
-
 
980
        $url = $this->out();
-
 
981
        // Does URL start with wwwroot? Otherwise, URL isn't relative to wwwroot.
-
 
982
        return ( ($url === $CFG->wwwroot) || (strpos($url, $CFG->wwwroot.'/') === 0) );
-
 
983
    }
-
 
984
 
-
 
985
    /**
-
 
986
     * Returns URL as relative path from $CFG->wwwroot
-
 
987
     *
-
 
988
     * Can be used for passing around urls with the wwwroot stripped
-
 
989
     *
-
 
990
     * @param boolean $escaped Use & as params separator instead of plain &
-
 
991
     * @param array $overrideparams params to add to the output url, these override existing ones with the same name.
-
 
992
     * @return string Resulting URL
-
 
993
     * @throws coding_exception if called on a non-local url
-
 
994
     */
-
 
995
    public function out_as_local_url($escaped = true, array $overrideparams = null) {
-
 
996
        global $CFG;
-
 
997
 
-
 
998
        // URL should be relative to wwwroot. If not then throw exception.
-
 
999
        if ($this->is_local_url()) {
-
 
1000
            $url = $this->out($escaped, $overrideparams);
-
 
1001
            $localurl = substr($url, strlen($CFG->wwwroot));
-
 
1002
            return !empty($localurl) ? $localurl : '';
-
 
1003
        } else {
-
 
1004
            throw new coding_exception('out_as_local_url called on a non-local URL');
-
 
1005
        }
-
 
1006
    }
-
 
1007
 
-
 
1008
    /**
-
 
1009
     * Returns the 'path' portion of a URL. For example, if the URL is
-
 
1010
     * http://www.example.org:447/my/file/is/here.txt?really=1 then this will
-
 
1011
     * return '/my/file/is/here.txt'.
-
 
1012
     *
-
 
1013
     * By default the path includes slash-arguments (for example,
-
 
1014
     * '/myfile.php/extra/arguments') so it is what you would expect from a
-
 
1015
     * URL path. If you don't want this behaviour, you can opt to exclude the
-
 
1016
     * slash arguments. (Be careful: if the $CFG variable slasharguments is
-
 
1017
     * disabled, these URLs will have a different format and you may need to
-
 
1018
     * look at the 'file' parameter too.)
-
 
1019
     *
-
 
1020
     * @param bool $includeslashargument If true, includes slash arguments
-
 
1021
     * @return string Path of URL
-
 
1022
     */
-
 
1023
    public function get_path($includeslashargument = true) {
-
 
1024
        return $this->path . ($includeslashargument ? $this->slashargument : '');
-
 
1025
    }
-
 
1026
 
-
 
1027
    /**
-
 
1028
     * Returns a given parameter value from the URL.
-
 
1029
     *
-
 
1030
     * @param string $name Name of parameter
-
 
1031
     * @return string Value of parameter or null if not set
-
 
1032
     */
-
 
1033
    public function get_param($name) {
-
 
1034
        if (array_key_exists($name, $this->params)) {
-
 
1035
            return $this->params[$name];
-
 
1036
        } else {
-
 
1037
            return null;
-
 
1038
        }
-
 
1039
    }
-
 
1040
 
-
 
1041
    /**
-
 
1042
     * Returns the 'scheme' portion of a URL. For example, if the URL is
-
 
1043
     * http://www.example.org:447/my/file/is/here.txt?really=1 then this will
-
 
1044
     * return 'http' (without the colon).
-
 
1045
     *
-
 
1046
     * @return string Scheme of the URL.
-
 
1047
     */
-
 
1048
    public function get_scheme() {
-
 
1049
        return $this->scheme;
-
 
1050
    }
-
 
1051
 
-
 
1052
    /**
-
 
1053
     * Returns the 'host' portion of a URL. For example, if the URL is
-
 
1054
     * http://www.example.org:447/my/file/is/here.txt?really=1 then this will
-
 
1055
     * return 'www.example.org'.
-
 
1056
     *
-
 
1057
     * @return string Host of the URL.
-
 
1058
     */
-
 
1059
    public function get_host() {
-
 
1060
        return $this->host;
-
 
1061
    }
-
 
1062
 
-
 
1063
    /**
-
 
1064
     * Returns the 'port' portion of a URL. For example, if the URL is
-
 
1065
     * http://www.example.org:447/my/file/is/here.txt?really=1 then this will
-
 
1066
     * return '447'.
-
 
1067
     *
-
 
1068
     * @return string Port of the URL.
-
 
1069
     */
-
 
1070
    public function get_port() {
-
 
1071
        return $this->port;
-
 
1072
    }
-
 
1073
}
-
 
1074
 
-
 
1075
/**
243
/**
1076
 * Determine if there is data waiting to be processed from a form
244
 * Determine if there is data waiting to be processed from a form
1077
 *
245
 *
1078
 * Used on most forms in Moodle to check for data
246
 * Used on most forms in Moodle to check for data
1079
 * Returns the data as an object, if it's found.
247
 * Returns the data as an object, if it's found.
Línea 1909... Línea 1077...
1909
        require_once $CFG->libdir.'/htmlpurifier/locallib.php';
1077
        require_once $CFG->libdir.'/htmlpurifier/locallib.php';
1910
        $config = HTMLPurifier_Config::createDefault();
1078
        $config = HTMLPurifier_Config::createDefault();
Línea 1911... Línea 1079...
1911
 
1079
 
1912
        $config->set('HTML.DefinitionID', 'moodlehtml');
1080
        $config->set('HTML.DefinitionID', 'moodlehtml');
-
 
1081
        $config->set('HTML.DefinitionRev', 7);
1913
        $config->set('HTML.DefinitionRev', 7);
1082
        $config->set('CSS.Proprietary', true);
1914
        $config->set('Cache.SerializerPath', $cachedir);
1083
        $config->set('Cache.SerializerPath', $cachedir);
1915
        $config->set('Cache.SerializerPermissions', $CFG->directorypermissions);
1084
        $config->set('Cache.SerializerPermissions', $CFG->directorypermissions);
1916
        $config->set('Core.NormalizeNewlines', false);
1085
        $config->set('Core.NormalizeNewlines', false);
1917
        $config->set('Core.ConvertDocumentToFragment', true);
1086
        $config->set('Core.ConvertDocumentToFragment', true);
Línea 2067... Línea 1236...
2067
 *
1236
 *
2068
 * @param string $text The markdown formatted text to be converted.
1237
 * @param string $text The markdown formatted text to be converted.
2069
 * @return string Converted text
1238
 * @return string Converted text
2070
 */
1239
 */
2071
function markdown_to_html($text) {
1240
function markdown_to_html($text) {
2072
    global $CFG;
-
 
2073
 
-
 
2074
    if ($text === '' or $text === null) {
1241
    if ($text === '' or $text === null) {
2075
        return $text;
1242
        return $text;
2076
    }
1243
    }
Línea 2077... Línea -...
2077
 
-
 
2078
    require_once($CFG->libdir .'/markdown/MarkdownInterface.php');
-
 
2079
    require_once($CFG->libdir .'/markdown/Markdown.php');
-
 
2080
    require_once($CFG->libdir .'/markdown/MarkdownExtra.php');
-
 
2081
 
1244
 
2082
    return \Michelf\MarkdownExtra::defaultTransform($text);
1245
    return \Michelf\MarkdownExtra::defaultTransform($text);
Línea 2083... Línea 1246...
2083
}
1246
}
2084
 
1247
 
Línea 2399... Línea 1562...
2399
        @header('Cache-Control: private, pre-check=0, post-check=0, max-age=0, no-transform');
1562
        @header('Cache-Control: private, pre-check=0, post-check=0, max-age=0, no-transform');
2400
        @header('Pragma: no-cache');
1563
        @header('Pragma: no-cache');
2401
        @header('Expires: ');
1564
        @header('Expires: ');
2402
    } else {
1565
    } else {
2403
        // Do everything we can to always prevent clients and proxies caching.
1566
        // Do everything we can to always prevent clients and proxies caching.
2404
        @header('Cache-Control: no-store, no-cache, must-revalidate');
1567
        @header('Cache-Control: no-store, no-cache, must-revalidate, no-transform');
2405
        @header('Cache-Control: post-check=0, pre-check=0, no-transform', false);
-
 
2406
        @header('Pragma: no-cache');
1568
        @header('Pragma: no-cache');
2407
        @header('Expires: Mon, 20 Aug 1969 09:23:00 GMT');
1569
        @header('Expires: Mon, 20 Aug 1969 09:23:00 GMT');
2408
        @header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
1570
        @header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
2409
    }
1571
    }
2410
    @header('Accept-Ranges: none');
1572
    @header('Accept-Ranges: none');
Línea 2849... Línea 2011...
2849
 
2011
 
2850
    return implode("\n", $menu);
2012
    return implode("\n", $menu);
Línea 2851... Línea 2013...
2851
}
2013
}
2852
 
-
 
2853
/**
-
 
2854
 * Prints a grade menu (as part of an existing form) with help showing all possible numerical grades and scales.
-
 
2855
 *
-
 
2856
 * @todo Finish documenting this function
-
 
2857
 * @todo Deprecate: this is only used in a few contrib modules
-
 
2858
 *
-
 
2859
 * @param int $courseid The course ID
-
 
2860
 * @param string $name
-
 
2861
 * @param string $current
-
 
2862
 * @param boolean $includenograde Include those with no grades
-
 
2863
 * @param boolean $return If set to true returns rather than echo's
-
 
2864
 * @return string|bool|null Depending on value of $return
-
 
2865
 */
-
 
2866
function print_grade_menu($courseid, $name, $current, $includenograde=true, $return=false) {
-
 
2867
    global $OUTPUT;
-
 
2868
 
-
 
2869
    $output = '';
-
 
2870
    $strscale = get_string('scale');
-
 
2871
    $strscales = get_string('scales');
-
 
2872
 
-
 
2873
    $scales = get_scales_menu($courseid);
-
 
2874
    foreach ($scales as $i => $scalename) {
-
 
2875
        $grades[-$i] = $strscale .': '. $scalename;
-
 
2876
    }
-
 
2877
    if ($includenograde) {
-
 
2878
        $grades[0] = get_string('nograde');
-
 
2879
    }
-
 
2880
    for ($i=100; $i>=1; $i--) {
-
 
2881
        $grades[$i] = $i;
-
 
2882
    }
-
 
2883
    $output .= html_writer::select($grades, $name, $current, false);
-
 
2884
 
-
 
2885
    $linkobject = '<span class="helplink">' . $OUTPUT->pix_icon('help', $strscales) . '</span>';
-
 
2886
    $link = new moodle_url('/course/scales.php', array('id' => $courseid, 'list' => 1));
-
 
2887
    $action = new popup_action('click', $link, 'ratingscales', array('height' => 400, 'width' => 500));
-
 
2888
    $output .= $OUTPUT->action_link($link, $linkobject, $action, array('title' => $strscales));
-
 
2889
 
-
 
2890
    if ($return) {
-
 
2891
        return $output;
-
 
2892
    } else {
-
 
2893
        echo $output;
-
 
2894
    }
-
 
2895
}
-
 
2896
 
2014
 
2897
/**
2015
/**
2898
 * Print an error to STDOUT and exit with a non-zero code. For commandline scripts.
2016
 * Print an error to STDOUT and exit with a non-zero code. For commandline scripts.
2899
 *
2017
 *
2900
 * Default errorcode is 1.
2018
 * Default errorcode is 1.
Línea 2955... Línea 2073...
2955
 * @param string $message The message to display to the user
2073
 * @param string $message The message to display to the user
2956
 * @param int $delay The delay before redirecting
2074
 * @param int $delay The delay before redirecting
2957
 * @param string $messagetype The type of notification to show the message in. See constants on \core\output\notification.
2075
 * @param string $messagetype The type of notification to show the message in. See constants on \core\output\notification.
2958
 * @throws moodle_exception
2076
 * @throws moodle_exception
2959
 */
2077
 */
2960
function redirect($url, $message='', $delay=null, $messagetype = \core\output\notification::NOTIFY_INFO) {
2078
function redirect($url, $message='', $delay=null, $messagetype = \core\output\notification::NOTIFY_INFO): Never {
2961
    global $OUTPUT, $PAGE, $CFG;
2079
    global $OUTPUT, $PAGE, $CFG;
Línea 2962... Línea 2080...
2962
 
2080
 
2963
    if (CLI_SCRIPT or AJAX_SCRIPT) {
2081
    if (CLI_SCRIPT or AJAX_SCRIPT) {
2964
        // This is wrong - developers should not use redirect in these scripts but it should not be very likely.
2082
        // This is wrong - developers should not use redirect in these scripts but it should not be very likely.
Línea 3463... Línea 2581...
3463
 
2581
 
3464
    return ($inpopup);
2582
    return ($inpopup);
Línea 3465... Línea 2583...
3465
}
2583
}
3466
 
-
 
3467
/**
-
 
3468
 * Progress trace class.
-
 
3469
 *
-
 
3470
 * Use this class from long operations where you want to output occasional information about
-
 
3471
 * what is going on, but don't know if, or in what format, the output should be.
-
 
3472
 *
-
 
3473
 * @copyright 2009 Tim Hunt
-
 
3474
 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
-
 
3475
 * @package core
-
 
3476
 */
-
 
3477
abstract class progress_trace {
-
 
3478
    /**
-
 
3479
     * Output an progress message in whatever format.
-
 
3480
     *
-
 
3481
     * @param string $message the message to output.
-
 
3482
     * @param integer $depth indent depth for this message.
-
 
3483
     */
-
 
3484
    abstract public function output($message, $depth = 0);
-
 
3485
 
-
 
3486
    /**
-
 
3487
     * Called when the processing is finished.
-
 
3488
     */
-
 
3489
    public function finished() {
-
 
3490
    }
-
 
3491
}
-
 
3492
 
-
 
3493
/**
-
 
3494
 * This subclass of progress_trace does not ouput anything.
-
 
3495
 *
-
 
3496
 * @copyright 2009 Tim Hunt
-
 
3497
 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
-
 
3498
 * @package core
-
 
3499
 */
-
 
3500
class null_progress_trace extends progress_trace {
-
 
3501
    /**
-
 
3502
     * Does Nothing
-
 
3503
     *
-
 
3504
     * @param string $message
-
 
3505
     * @param int $depth
-
 
3506
     * @return void Does Nothing
-
 
3507
     */
-
 
3508
    public function output($message, $depth = 0) {
-
 
3509
    }
-
 
3510
}
-
 
3511
 
-
 
3512
/**
-
 
3513
 * This subclass of progress_trace outputs to plain text.
-
 
3514
 *
-
 
3515
 * @copyright 2009 Tim Hunt
-
 
3516
 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
-
 
3517
 * @package core
-
 
3518
 */
-
 
3519
class text_progress_trace extends progress_trace {
-
 
3520
    /**
-
 
3521
     * Output the trace message.
-
 
3522
     *
-
 
3523
     * @param string $message
-
 
3524
     * @param int $depth
-
 
3525
     * @return void Output is echo'd
-
 
3526
     */
-
 
3527
    public function output($message, $depth = 0) {
-
 
3528
        mtrace(str_repeat('  ', $depth) . $message);
-
 
3529
    }
-
 
3530
}
-
 
3531
 
-
 
3532
/**
-
 
3533
 * This subclass of progress_trace outputs as HTML.
-
 
3534
 *
-
 
3535
 * @copyright 2009 Tim Hunt
-
 
3536
 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
-
 
3537
 * @package core
-
 
3538
 */
-
 
3539
class html_progress_trace extends progress_trace {
-
 
3540
    /**
-
 
3541
     * Output the trace message.
-
 
3542
     *
-
 
3543
     * @param string $message
-
 
3544
     * @param int $depth
-
 
3545
     * @return void Output is echo'd
-
 
3546
     */
-
 
3547
    public function output($message, $depth = 0) {
-
 
3548
        echo '<p>', str_repeat('&#160;&#160;', $depth), htmlspecialchars($message, ENT_COMPAT), "</p>\n";
-
 
3549
        flush();
-
 
3550
    }
-
 
3551
}
-
 
3552
 
-
 
3553
/**
-
 
3554
 * HTML List Progress Tree
-
 
3555
 *
-
 
3556
 * @copyright 2009 Tim Hunt
-
 
3557
 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
-
 
3558
 * @package core
-
 
3559
 */
-
 
3560
class html_list_progress_trace extends progress_trace {
-
 
3561
    /** @var int */
-
 
3562
    protected $currentdepth = -1;
-
 
3563
 
-
 
3564
    /**
-
 
3565
     * Echo out the list
-
 
3566
     *
-
 
3567
     * @param string $message The message to display
-
 
3568
     * @param int $depth
-
 
3569
     * @return void Output is echoed
-
 
3570
     */
-
 
3571
    public function output($message, $depth = 0) {
-
 
3572
        $samedepth = true;
-
 
3573
        while ($this->currentdepth > $depth) {
-
 
3574
            echo "</li>\n</ul>\n";
-
 
3575
            $this->currentdepth -= 1;
-
 
3576
            if ($this->currentdepth == $depth) {
-
 
3577
                echo '<li>';
-
 
3578
            }
-
 
3579
            $samedepth = false;
-
 
3580
        }
-
 
3581
        while ($this->currentdepth < $depth) {
-
 
3582
            echo "<ul>\n<li>";
-
 
3583
            $this->currentdepth += 1;
-
 
3584
            $samedepth = false;
-
 
3585
        }
-
 
3586
        if ($samedepth) {
-
 
3587
            echo "</li>\n<li>";
-
 
3588
        }
-
 
3589
        echo htmlspecialchars($message, ENT_COMPAT);
-
 
3590
        flush();
-
 
3591
    }
-
 
3592
 
-
 
3593
    /**
-
 
3594
     * Called when the processing is finished.
-
 
3595
     */
-
 
3596
    public function finished() {
-
 
3597
        while ($this->currentdepth >= 0) {
-
 
3598
            echo "</li>\n</ul>\n";
-
 
3599
            $this->currentdepth -= 1;
-
 
3600
        }
-
 
3601
    }
-
 
3602
}
-
 
3603
 
-
 
3604
/**
-
 
3605
 * This subclass of progress_trace outputs to error log.
-
 
3606
 *
-
 
3607
 * @copyright Petr Skoda {@link http://skodak.org}
-
 
3608
 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
-
 
3609
 * @package core
-
 
3610
 */
-
 
3611
class error_log_progress_trace extends progress_trace {
-
 
3612
    /** @var string log prefix */
-
 
3613
    protected $prefix;
-
 
3614
 
-
 
3615
    /**
-
 
3616
     * Constructor.
-
 
3617
     * @param string $prefix optional log prefix
-
 
3618
     */
-
 
3619
    public function __construct($prefix = '') {
-
 
3620
        $this->prefix = $prefix;
-
 
3621
    }
-
 
3622
 
-
 
3623
    /**
-
 
3624
     * Output the trace message.
-
 
3625
     *
-
 
3626
     * @param string $message
-
 
3627
     * @param int $depth
-
 
3628
     * @return void Output is sent to error log.
-
 
3629
     */
-
 
3630
    public function output($message, $depth = 0) {
-
 
3631
        error_log($this->prefix . str_repeat('  ', $depth) . $message);
-
 
3632
    }
-
 
3633
}
-
 
3634
 
-
 
3635
/**
-
 
3636
 * Special type of trace that can be used for catching of output of other traces.
-
 
3637
 *
-
 
3638
 * @copyright Petr Skoda {@link http://skodak.org}
-
 
3639
 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
-
 
3640
 * @package core
-
 
3641
 */
-
 
3642
class progress_trace_buffer extends progress_trace {
-
 
3643
    /** @var progress_trace */
-
 
3644
    protected $trace;
-
 
3645
    /** @var bool do we pass output out */
-
 
3646
    protected $passthrough;
-
 
3647
    /** @var string output buffer */
-
 
3648
    protected $buffer;
-
 
3649
 
-
 
3650
    /**
-
 
3651
     * Constructor.
-
 
3652
     *
-
 
3653
     * @param progress_trace $trace
-
 
3654
     * @param bool $passthrough true means output and buffer, false means just buffer and no output
-
 
3655
     */
-
 
3656
    public function __construct(progress_trace $trace, $passthrough = true) {
-
 
3657
        $this->trace       = $trace;
-
 
3658
        $this->passthrough = $passthrough;
-
 
3659
        $this->buffer      = '';
-
 
3660
    }
-
 
3661
 
-
 
3662
    /**
-
 
3663
     * Output the trace message.
-
 
3664
     *
-
 
3665
     * @param string $message the message to output.
-
 
3666
     * @param int $depth indent depth for this message.
-
 
3667
     * @return void output stored in buffer
-
 
3668
     */
-
 
3669
    public function output($message, $depth = 0) {
-
 
3670
        ob_start();
-
 
3671
        $this->trace->output($message, $depth);
-
 
3672
        $this->buffer .= ob_get_contents();
-
 
3673
        if ($this->passthrough) {
-
 
3674
            ob_end_flush();
-
 
3675
        } else {
-
 
3676
            ob_end_clean();
-
 
3677
        }
-
 
3678
    }
-
 
3679
 
-
 
3680
    /**
-
 
3681
     * Called when the processing is finished.
-
 
3682
     */
-
 
3683
    public function finished() {
-
 
3684
        ob_start();
-
 
3685
        $this->trace->finished();
-
 
3686
        $this->buffer .= ob_get_contents();
-
 
3687
        if ($this->passthrough) {
-
 
3688
            ob_end_flush();
-
 
3689
        } else {
-
 
3690
            ob_end_clean();
-
 
3691
        }
-
 
3692
    }
-
 
3693
 
-
 
3694
    /**
-
 
3695
     * Reset internal text buffer.
-
 
3696
     */
-
 
3697
    public function reset_buffer() {
-
 
3698
        $this->buffer = '';
-
 
3699
    }
-
 
3700
 
-
 
3701
    /**
-
 
3702
     * Return internal text buffer.
-
 
3703
     * @return string buffered plain text
-
 
3704
     */
-
 
3705
    public function get_buffer() {
-
 
3706
        return $this->buffer;
-
 
3707
    }
-
 
3708
}
-
 
3709
 
-
 
3710
/**
-
 
3711
 * Special type of trace that can be used for redirecting to multiple other traces.
-
 
3712
 *
-
 
3713
 * @copyright Petr Skoda {@link http://skodak.org}
-
 
3714
 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
-
 
3715
 * @package core
-
 
3716
 */
-
 
3717
class combined_progress_trace extends progress_trace {
-
 
3718
 
-
 
3719
    /**
-
 
3720
     * An array of traces.
-
 
3721
     * @var array
-
 
3722
     */
-
 
3723
    protected $traces;
-
 
3724
 
-
 
3725
    /**
-
 
3726
     * Constructs a new instance.
-
 
3727
     *
-
 
3728
     * @param array $traces multiple traces
-
 
3729
     */
-
 
3730
    public function __construct(array $traces) {
-
 
3731
        $this->traces = $traces;
-
 
3732
    }
-
 
3733
 
-
 
3734
    /**
-
 
3735
     * Output an progress message in whatever format.
-
 
3736
     *
-
 
3737
     * @param string $message the message to output.
-
 
3738
     * @param integer $depth indent depth for this message.
-
 
3739
     */
-
 
3740
    public function output($message, $depth = 0) {
-
 
3741
        foreach ($this->traces as $trace) {
-
 
3742
            $trace->output($message, $depth);
-
 
3743
        }
-
 
3744
    }
-
 
3745
 
-
 
3746
    /**
-
 
3747
     * Called when the processing is finished.
-
 
3748
     */
-
 
3749
    public function finished() {
-
 
3750
        foreach ($this->traces as $trace) {
-
 
3751
            $trace->finished();
-
 
3752
        }
-
 
3753
    }
-
 
3754
}
-
 
3755
 
2584
 
3756
/**
2585
/**
3757
 * Returns a localized sentence in the current language summarizing the current password policy
2586
 * Returns a localized sentence in the current language summarizing the current password policy
3758
 *
2587
 *
3759
 * @todo this should be handled by a function/method in the language pack library once we have a support for it
2588
 * @todo this should be handled by a function/method in the language pack library once we have a support for it
Línea 3845... Línea 2674...
3845
        // Should be simple wiki only MDL-21695.
2674
        // Should be simple wiki only MDL-21695.
3846
        $data->text = format_text(get_string($identifier.'_help', $component, $a), FORMAT_MARKDOWN, $options);
2675
        $data->text = format_text(get_string($identifier.'_help', $component, $a), FORMAT_MARKDOWN, $options);
Línea 3847... Línea 2676...
3847
 
2676
 
3848
        $helplink = $identifier . '_link';
2677
        $helplink = $identifier . '_link';
-
 
2678
        if ($sm->string_exists($helplink, $component)) {  // Link to further info in Moodle docs.
3849
        if ($sm->string_exists($helplink, $component)) {  // Link to further info in Moodle docs.
2679
            // The link is stored in a language file but should not be translated, use value for English.
-
 
2680
            $link = $sm->get_string($helplink, $component, null, 'en');
3850
            $link = get_string($helplink, $component);
2681
            // The text 'More help' should be in the current language.
Línea 3851... Línea 2682...
3851
            $linktext = get_string('morehelp');
2682
            $linktext = get_string('morehelp');
3852
 
2683
 
3853
            $data->doclink = new stdClass();
2684
            $data->doclink = new stdClass();