Proyectos de Subversion Moodle

Rev

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

Rev 1 Rev 1441
Línea 13... Línea 13...
13
//
13
//
14
// You should have received a copy of the GNU General Public License
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/>.
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
Línea 16... Línea 16...
16
 
16
 
17
/**
17
/**
18
 *  Media plugin filtering
18
 * File only retained to prevent fatal errors in code that tries to require/include this.
19
 *
19
 *
20
 *  This filter will replace any links to a media file with
20
 * @todo MDL-82708 delete this file as part of Moodle 6.0 development.
21
 *  a media plugin that plays that media inline
-
 
22
 *
-
 
23
 * @package    filter
21
 * @deprecated This file is no longer required in Moodle 4.5+.
24
 * @subpackage mediaplugin
22
 * @package filter_mediaplugin
25
 * @copyright  2004 onwards Martin Dougiamas  {@link http://moodle.com}
23
 * @copyright Martin Dougiamas  {@link http://moodle.com}
26
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24
 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
27
 */
-
 
28
 
25
 */
Línea 29... Línea -...
29
defined('MOODLE_INTERNAL') || die();
-
 
30
 
-
 
31
/**
-
 
32
 * Automatic media embedding filter class.
-
 
33
 *
-
 
34
 * It is highly recommended to configure servers to be compatible with our slasharguments,
-
 
35
 * otherwise the "?d=600x400" may not work.
-
 
36
 *
-
 
37
 * @package    filter
-
 
38
 * @subpackage mediaplugin
-
 
39
 * @copyright  2004 onwards Martin Dougiamas  {@link http://moodle.com}
-
 
40
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
-
 
41
 */
-
 
42
class filter_mediaplugin extends moodle_text_filter {
-
 
43
    /** @var bool True if currently filtering trusted text */
-
 
44
    private $trusted;
-
 
45
 
-
 
46
    /**
-
 
47
     * Setup page with filter requirements and other prepare stuff.
-
 
48
     *
-
 
49
     * @param moodle_page $page The page we are going to add requirements to.
-
 
50
     * @param context $context The context which contents are going to be filtered.
-
 
51
     */
-
 
52
    public function setup($page, $context) {
-
 
53
        // This only requires execution once per request.
-
 
54
        static $jsinitialised = false;
-
 
55
        if ($jsinitialised) {
-
 
56
            return;
-
 
57
        }
-
 
58
        $jsinitialised = true;
-
 
59
 
-
 
60
        // Set up the media manager so that media plugins requiring JS are initialised.
-
 
61
        $mediamanager = core_media_manager::instance($page);
-
 
62
    }
-
 
63
 
-
 
64
    public function filter($text, array $options = array()) {
-
 
65
        global $CFG, $PAGE;
-
 
66
 
-
 
67
        if (!is_string($text) or empty($text)) {
-
 
68
            // non string data can not be filtered anyway
-
 
69
            return $text;
-
 
70
        }
-
 
71
 
-
 
72
        if (stripos($text, '</a>') === false && stripos($text, '</video>') === false && stripos($text, '</audio>') === false) {
-
 
73
            // Performance shortcut - if there are no </a>, </video> or </audio> tags, nothing can match.
-
 
74
            return $text;
-
 
75
        }
-
 
76
 
-
 
77
        // Check permissions.
-
 
78
        $this->trusted = !empty($options['noclean']) or !empty($CFG->allowobjectembed);
-
 
79
 
-
 
80
        // Looking for tags.
-
 
81
        $matches = preg_split('/(<[^>]*>)/i', $text, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
-
 
82
 
-
 
83
        if (!$matches) {
-
 
84
            return $text;
-
 
85
        }
-
 
86
 
-
 
87
        // Regex to find media extensions in an <a> tag.
-
 
88
        $embedmarkers = core_media_manager::instance()->get_embeddable_markers();
-
 
89
        $re = '~<a\s[^>]*href="([^"]*(?:' .  $embedmarkers . ')[^"]*)"[^>]*>([^>]*)</a>~is';
-
 
90
 
-
 
91
        $newtext = '';
-
 
92
        $validtag = '';
-
 
93
        $tagname = '';
-
 
94
        $sizeofmatches = count($matches);
-
 
95
 
-
 
96
        // We iterate through the given string to find valid <a> tags
-
 
97
        // and build them so that the callback function can check it for
-
 
98
        // embedded content. Then we rebuild the string.
-
 
99
        foreach ($matches as $idx => $tag) {
-
 
100
            if (preg_match('|</'.$tagname.'>|', $tag) && !empty($validtag)) {
-
 
101
                $validtag .= $tag;
-
 
102
 
-
 
103
                // Given we now have a valid <a> tag to process it's time for
-
 
104
                // ReDoS protection. Stop processing if a word is too large.
-
 
105
                if (strlen($validtag) < 4096) {
-
 
106
                    if ($tagname === 'a') {
-
 
107
                        $processed = preg_replace_callback($re, array($this, 'callback'), $validtag);
26
defined('MOODLE_INTERNAL') || die();
108
                    } else {
-
 
109
                        // For audio and video tags we just process them without precheck for embeddable markers.
-
 
110
                        $processed = $this->process_media_tag($validtag);
-
 
111
                    }
-
 
112
                }
-
 
113
                // Rebuilding the string with our new processed text.
-
 
114
                $newtext .= !empty($processed) ? $processed : $validtag;
-
 
115
                // Wipe it so we can catch any more instances to filter.
-
 
116
                $validtag = '';
-
 
117
                $processed = '';
-
 
118
            } else if (preg_match('/<(a|video|audio)\s[^>]*/', $tag, $tagmatches) && $sizeofmatches > 1 &&
-
 
119
                    (empty($validtag) || $tagname === strtolower($tagmatches[1]))) {
-
 
120
                // Looking for a starting tag. Ignore tags embedded into each other.
-
 
121
                $validtag = $tag;
-
 
122
                $tagname = strtolower($tagmatches[1]);
-
 
123
            } else {
-
 
124
                // If we have a validtag add to that to process later,
-
 
125
                // else add straight onto our newtext string.
-
 
126
                if (!empty($validtag)) {
-
 
127
                    $validtag .= $tag;
-
 
128
                } else {
-
 
129
                    $newtext .= $tag;
-
 
130
                }
-
 
131
            }
-
 
132
        }
-
 
133
 
-
 
134
        // Return the same string except processed by the above.
-
 
135
        return $newtext;
-
 
136
    }
-
 
137
 
-
 
138
    /**
-
 
139
     * Replace link with embedded content, if supported.
-
 
140
     *
-
 
141
     * @param array $matches
-
 
142
     * @return string
-
 
143
     */
-
 
144
    private function callback(array $matches) {
-
 
145
        $mediamanager = core_media_manager::instance();
-
 
146
 
-
 
147
        global $CFG, $PAGE;
-
 
148
        // Check if we ignore it.
-
 
149
        if (preg_match('/class="[^"]*nomediaplugin/i', $matches[0])) {
-
 
150
            return $matches[0];
-
 
151
        }
-
 
152
 
-
 
153
        // Get name.
-
 
154
        $name = trim($matches[2]);
-
 
155
        if (empty($name) or strpos($name, 'http') === 0) {
-
 
156
            $name = ''; // Use default name.
-
 
157
        }
-
 
158
 
-
 
159
        // Split provided URL into alternatives.
-
 
160
        $urls = $mediamanager->split_alternatives($matches[1], $width, $height);
-
 
161
 
-
 
162
        $options = [core_media_manager::OPTION_ORIGINAL_TEXT => $matches[0]];
-
 
163
        return $this->embed_alternatives($urls, $name, $width, $height, $options);
-
 
164
    }
-
 
165
 
-
 
166
    /**
-
 
167
     * Renders media files (audio or video) using suitable embedded player.
-
 
168
     *
-
 
169
     * Wrapper for {@link core_media_manager::embed_alternatives()}
-
 
170
     *
-
 
171
     * @param array $urls Array of moodle_url to media files
-
 
172
     * @param string $name Optional user-readable name to display in download link
-
 
173
     * @param int $width Width in pixels (optional)
-
 
174
     * @param int $height Height in pixels (optional)
-
 
175
     * @param array $options Array of key/value pairs
-
 
176
     * @return string HTML content of embed
-
 
177
     */
-
 
178
    protected function embed_alternatives($urls, $name, $width, $height, $options) {
-
 
179
 
-
 
180
        // Allow trusted content (or not).
-
 
181
        if ($this->trusted) {
-
 
182
            $options[core_media_manager::OPTION_TRUSTED] = true;
-
 
183
        }
-
 
184
 
-
 
185
        // We could test whether embed is possible using can_embed, but to save
-
 
186
        // time, let's just embed it with the 'fallback to blank' option which
-
 
187
        // does most of the same stuff anyhow.
-
 
188
        $options[core_media_manager::OPTION_FALLBACK_TO_BLANK] = true;
-
 
189
 
-
 
190
        // NOTE: Options are not passed through from filter because the 'embed'
-
 
191
        // code does not recognise filter options (it's a different kind of
-
 
192
        // option-space) as it can be used in non-filter situations.
-
 
193
        $result = core_media_manager::instance()->embed_alternatives($urls, $name, $width, $height, $options);
-
 
194
 
-
 
195
        // If something was embedded, return it, otherwise return original.
-
 
196
        if ($result !== '') {
-
 
197
            return $result;
-
 
198
        } else {
-
 
199
            return $options[core_media_manager::OPTION_ORIGINAL_TEXT];
-
 
200
        }
-
 
201
    }
-
 
202
 
-
 
203
    /**
-
 
204
     * Replaces <video> or <audio> tag with processed contents
-
 
205
     *
-
 
206
     * @param string $fulltext complete HTML snipped "<video ...>...</video>" or "<audio ...>....</audio>"
-
 
207
     * @return string
-
 
208
     */
-
 
209
    protected function process_media_tag($fulltext) {
-
 
210
        // Check if we ignore it.
-
 
211
        if (preg_match('/^<[^>]*class="[^"]*nomediaplugin/im', $fulltext)) {
-
 
212
            return $fulltext;
-
 
213
        }
-
 
214
 
-
 
215
        // Find all sources both as <video src=""> and as embedded <source> tags.
-
 
216
        $urls = [];
-
 
217
        if (preg_match('/^<[^>]*\bsrc="(.*?)"/im', $fulltext, $matches)) {
-
 
218
            $urls[] = new moodle_url($matches[1]);
-
 
219
        }
-
 
220
        if (preg_match_all('/<source\b[^>]*\bsrc="(.*?)"/im', $fulltext, $matches)) {
-
 
221
            foreach ($matches[1] as $url) {
-
 
222
                $urls[] = new moodle_url($url);
-
 
223
            }
-
 
224
        }
-
 
225
        // Extract width/height/title attributes and call embed_alternatives to find a suitable media player.
-
 
226
        if ($urls) {
-
 
227
            $options = [core_media_manager::OPTION_ORIGINAL_TEXT => $fulltext];
-
 
228
            $width = core_media_player_native::get_attribute($fulltext, 'width', PARAM_INT);
-
 
229
            $height = core_media_player_native::get_attribute($fulltext, 'height', PARAM_INT);
-
 
230
            $name = core_media_player_native::get_attribute($fulltext, 'title');
-
 
231
            return $this->embed_alternatives($urls, $name, $width, $height, $options);
-
 
232
        }
-
 
233
        return $fulltext;
-