-
Notifications
You must be signed in to change notification settings - Fork 0
/
filter.php
113 lines (94 loc) · 3.45 KB
/
filter.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* External link filtering
*
* This filter will replace any external links
* with a target of _blank
*
* @package filter
* @subpackage urlopenext
*/
defined('MOODLE_INTERNAL') || die();
/**
* External link modifier.
*
*
* @package filter
* @subpackage urlopenext
*/
class filter_urlopenext extends moodle_text_filter {
/** @var bool True if currently filtering trusted text */
private $trusted;
public function filter($text, array $options = array()) {
global $CFG, $PAGE;
if (!is_string($text) or empty($text)) {
// non string data can not be filtered anyway
return $text;
}
if (stripos($text, '</a>') === false) {
// Performance shortcut - if there are no </a> tags, nothing can match.
return $text;
}
// Check SWF permissions.
$this->trusted = !empty($options['noclean']) or !empty($CFG->allowobjectembed);
//Find entire a tags and trigger callback
$result = preg_replace_callback('/<\s*a[^>]*>[\s\S]*?<\s*\/\s*a>/i', array($this, 'callback'), $text);
// Return the same string except processed by the above.
return $result;
}
/**
* Replace external link to open in new window.
*
* @param array $matches
* @return string
*/
private function callback(array $matches) {
global $CFG, $PAGE;
//Don't run if string excessively long
if (strlen($matches[0]) > 4096) {
return $matches[0];
}
//Convert a tag string to php dom
$dom = new DOMDocument;
$html_data = mb_convert_encoding($matches[0], 'HTML-ENTITIES', 'UTF-8');
$dom->loadHTML($html_data, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$links = $dom->getElementsByTagName('a');
//Determine if external or internal
//Checks if url host matches with moodle hostt
foreach ($links as $link) {
$domain = parse_url($CFG->wwwroot);
$href = parse_url($link->getAttribute('href'));
if($href === "")
return $matches[0];
if(!array_key_exists('host', $href))
return $matches[0];
if($domain['host'] !== $href['host']){
$alert = $dom->createElement('span', ' (new window)');
$alert->setAttribute('class', "sr-only");
$icon = $dom->createElement('i');
$icon->setAttribute('class', "icon fa fa fa-external-link");
$icon->setAttribute('style', "margin: 0 0 0 .2rem;");
$link->setAttribute('target', '_blank');
$link->appendChild($icon);
$link->appendChild($alert);
$html = $dom->saveHTML();
return $html;
}
}
return $matches[0];
}
}