Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
 
3
// This file is part of Moodle - http://moodle.org/
4
//
5
// Moodle is free software: you can redistribute it and/or modify
6
// it under the terms of the GNU General Public License as published by
7
// the Free Software Foundation, either version 3 of the License, or
8
// (at your option) any later version.
9
//
10
// Moodle is distributed in the hope that it will be useful,
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
// GNU General Public License for more details.
14
//
15
// You should have received a copy of the GNU General Public License
16
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
17
 
18
/**
19
 * Private resource module utility functions
20
 *
21
 * @package    mod_resource
22
 * @copyright  2009 Petr Skoda  {@link http://skodak.org}
23
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24
 */
25
 
26
defined('MOODLE_INTERNAL') || die;
27
 
28
require_once("$CFG->libdir/filelib.php");
29
require_once("$CFG->libdir/resourcelib.php");
30
require_once("$CFG->dirroot/mod/resource/lib.php");
31
 
32
/**
33
 * Redirected to migrated resource if needed,
34
 * return if incorrect parameters specified
35
 * @param int $oldid
36
 * @param int $cmid
37
 * @return void
38
 */
39
function resource_redirect_if_migrated($oldid, $cmid) {
40
    global $DB, $CFG;
41
 
42
    if ($oldid) {
43
        $old = $DB->get_record('resource_old', array('oldid'=>$oldid));
44
    } else {
45
        $old = $DB->get_record('resource_old', array('cmid'=>$cmid));
46
    }
47
 
48
    if (!$old) {
49
        return;
50
    }
51
 
52
    redirect("$CFG->wwwroot/mod/$old->newmodule/view.php?id=".$old->cmid);
53
}
54
 
55
/**
56
 * Display embedded resource file.
57
 * @param object $resource
58
 * @param object $cm
59
 * @param object $course
60
 * @param stored_file $file main file
61
 * @return does not return
62
 */
63
function resource_display_embed($resource, $cm, $course, $file) {
64
    global $PAGE, $OUTPUT;
65
 
66
    $clicktoopen = resource_get_clicktoopen($file, $resource->revision);
67
 
68
    $context = context_module::instance($cm->id);
69
    $moodleurl = moodle_url::make_pluginfile_url($context->id, 'mod_resource', 'content', $resource->revision,
70
            $file->get_filepath(), $file->get_filename());
71
 
72
    $mimetype = $file->get_mimetype();
73
    $title    = $resource->name;
74
 
75
    $extension = resourcelib_get_extension($file->get_filename());
76
 
77
    $mediamanager = core_media_manager::instance($PAGE);
78
    $embedoptions = array(
79
        core_media_manager::OPTION_TRUSTED => true,
80
        core_media_manager::OPTION_BLOCK => true,
81
    );
82
 
83
    if (file_mimetype_in_typegroup($mimetype, 'web_image')) {  // It's an image
84
        $code = resourcelib_embed_image($moodleurl->out(), $title);
85
 
86
    } else if ($mimetype === 'application/pdf') {
87
        // PDF document
88
        $code = resourcelib_embed_pdf($moodleurl->out(), $title, $clicktoopen);
89
 
90
    } else if ($mediamanager->can_embed_url($moodleurl, $embedoptions)) {
91
        // Media (audio/video) file.
92
        $code = $mediamanager->embed_url($moodleurl, $title, 0, 0, $embedoptions);
93
 
94
    } else {
95
        // We need a way to discover if we are loading remote docs inside an iframe.
96
        $moodleurl->param('embed', 1);
97
 
98
        // anything else - just try object tag enlarged as much as possible
99
        $code = resourcelib_embed_general($moodleurl, $title, $clicktoopen, $mimetype);
100
    }
101
 
102
    // Let the module handle the display.
103
    $PAGE->activityheader->set_description(resource_get_intro($resource, $cm));
104
 
105
    resource_print_header($resource, $cm, $course);
106
 
107
    echo format_text($code, FORMAT_HTML, ['noclean' => true]);
108
 
109
    echo $OUTPUT->footer();
110
    die;
111
}
112
 
113
/**
114
 * Display resource frames.
115
 * @param object $resource
116
 * @param object $cm
117
 * @param object $course
118
 * @param stored_file $file main file
119
 * @return does not return
120
 */
121
function resource_display_frame($resource, $cm, $course, $file) {
122
    global $PAGE, $OUTPUT, $CFG;
123
 
124
    $frame = optional_param('frameset', 'main', PARAM_ALPHA);
125
 
126
    if ($frame === 'top') {
127
        $PAGE->set_pagelayout('frametop');
128
        $PAGE->activityheader->set_description(resource_get_intro($resource, $cm, true));
129
        resource_print_header($resource, $cm, $course);
130
        echo $OUTPUT->footer();
131
        die;
132
 
133
    } else {
134
        $config = get_config('resource');
135
        $context = context_module::instance($cm->id);
136
        $path = '/'.$context->id.'/mod_resource/content/'.$resource->revision.$file->get_filepath().$file->get_filename();
137
        $fileurl = file_encode_url($CFG->wwwroot.'/pluginfile.php', $path, false);
138
        $navurl = "$CFG->wwwroot/mod/resource/view.php?id=$cm->id&amp;frameset=top";
139
        $title = strip_tags(format_string($course->shortname.': '.$resource->name));
140
        $framesize = $config->framesize;
141
        $contentframetitle = s(format_string($resource->name));
142
        $modulename = s(get_string('modulename','resource'));
143
        $dir = get_string('thisdirection', 'langconfig');
144
 
145
        $file = <<<EOF
146
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
147
<html dir="$dir">
148
  <head>
149
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
150
    <title>$title</title>
151
  </head>
152
  <frameset rows="$framesize,*">
153
    <frame src="$navurl" title="$modulename" />
154
    <frame src="$fileurl" title="$contentframetitle" />
155
  </frameset>
156
</html>
157
EOF;
158
 
159
        @header('Content-Type: text/html; charset=utf-8');
160
        echo $file;
161
        die;
162
    }
163
}
164
 
165
/**
166
 * Internal function - create click to open text with link.
167
 */
168
function resource_get_clicktoopen($file, $revision, $extra='') {
169
    global $CFG;
170
 
171
    $filename = $file->get_filename();
172
    $path = '/'.$file->get_contextid().'/mod_resource/content/'.$revision.$file->get_filepath().$file->get_filename();
173
    $fullurl = file_encode_url($CFG->wwwroot.'/pluginfile.php', $path, false);
174
 
175
    $string = get_string('clicktoopen2', 'resource', "<a href=\"$fullurl\" $extra>$filename</a>");
176
 
177
    return $string;
178
}
179
 
180
/**
181
 * Internal function - create click to open text with link.
182
 */
183
function resource_get_clicktodownload($file, $revision) {
184
    global $CFG;
185
 
186
    $filename = $file->get_filename();
187
    $path = '/'.$file->get_contextid().'/mod_resource/content/'.$revision.$file->get_filepath().$file->get_filename();
188
    $fullurl = file_encode_url($CFG->wwwroot.'/pluginfile.php', $path, true);
189
 
190
    $string = get_string('clicktodownload', 'resource', "<a href=\"$fullurl\">$filename</a>");
191
 
192
    return $string;
193
}
194
 
195
/**
196
 * Print resource info and workaround link when JS not available.
197
 * @param object $resource
198
 * @param object $cm
199
 * @param object $course
200
 * @param stored_file $file main file
201
 * @return does not return
202
 */
203
function resource_print_workaround($resource, $cm, $course, $file) {
204
    global $CFG, $OUTPUT, $PAGE;
205
 
206
    // Let the module handle the display.
207
    $PAGE->activityheader->set_description(resource_get_intro($resource, $cm, true));
208
 
209
    resource_print_header($resource, $cm, $course);
210
 
211
    $resource->mainfile = $file->get_filename();
212
    echo '<div class="resourceworkaround">';
213
    switch (resource_get_final_display_type($resource)) {
214
        case RESOURCELIB_DISPLAY_POPUP:
215
            $path = '/'.$file->get_contextid().'/mod_resource/content/'.$resource->revision.$file->get_filepath().$file->get_filename();
216
            $fullurl = file_encode_url($CFG->wwwroot.'/pluginfile.php', $path, false);
217
            $options = empty($resource->displayoptions) ? [] : (array) unserialize_array($resource->displayoptions);
218
            $width  = empty($options['popupwidth'])  ? 620 : $options['popupwidth'];
219
            $height = empty($options['popupheight']) ? 450 : $options['popupheight'];
220
            $wh = "width=$width,height=$height,toolbar=no,location=no,menubar=no,copyhistory=no,status=no,directories=no,scrollbars=yes,resizable=yes";
221
            $extra = "onclick=\"window.open('$fullurl', '', '$wh'); return false;\"";
222
            echo resource_get_clicktoopen($file, $resource->revision, $extra);
223
            break;
224
 
225
        case RESOURCELIB_DISPLAY_NEW:
226
            $extra = 'onclick="this.target=\'_blank\'"';
227
            echo resource_get_clicktoopen($file, $resource->revision, $extra);
228
            break;
229
 
230
        case RESOURCELIB_DISPLAY_DOWNLOAD:
231
            echo resource_get_clicktodownload($file, $resource->revision);
232
            break;
233
 
234
        case RESOURCELIB_DISPLAY_OPEN:
235
        default:
236
            echo resource_get_clicktoopen($file, $resource->revision);
237
            break;
238
    }
239
    echo '</div>';
240
 
241
    echo $OUTPUT->footer();
242
    die;
243
}
244
 
245
/**
246
 * Print resource header.
247
 * @param object $resource
248
 * @param object $cm
249
 * @param object $course
250
 * @return void
251
 */
252
function resource_print_header($resource, $cm, $course) {
253
    global $PAGE, $OUTPUT;
254
 
255
    $PAGE->set_title($course->shortname.': '.$resource->name);
256
    $PAGE->set_heading($course->fullname);
257
    $PAGE->set_activity_record($resource);
258
    echo $OUTPUT->header();
259
}
260
 
261
/**
262
 * Gets details of the file to cache in course cache to be displayed using {@link resource_get_optional_details()}
263
 *
264
 * @param object $resource Resource table row (only property 'displayoptions' is used here)
265
 * @param object $cm Course-module table row
266
 * @return string Size and type or empty string if show options are not enabled
267
 */
268
function resource_get_file_details($resource, $cm) {
269
    $options = empty($resource->displayoptions) ? [] : (array) unserialize_array($resource->displayoptions);
270
    $filedetails = array();
271
    if (!empty($options['showsize']) || !empty($options['showtype']) || !empty($options['showdate'])) {
272
        $context = context_module::instance($cm->id);
273
        $fs = get_file_storage();
274
        $files = $fs->get_area_files($context->id, 'mod_resource', 'content', 0, 'sortorder DESC, id ASC', false);
275
        // For a typical file resource, the sortorder is 1 for the main file
276
        // and 0 for all other files. This sort approach is used just in case
277
        // there are situations where the file has a different sort order.
278
        $mainfile = $files ? reset($files) : null;
279
        if (!empty($options['showsize'])) {
280
            $filedetails['size'] = 0;
281
            foreach ($files as $file) {
282
                // This will also synchronize the file size for external files if needed.
283
                $filedetails['size'] += $file->get_filesize();
284
                if ($file->get_repository_id()) {
285
                    // If file is a reference the 'size' attribute can not be cached.
286
                    $filedetails['isref'] = true;
287
                }
288
            }
289
        }
290
        if (!empty($options['showtype'])) {
291
            if ($mainfile) {
292
                $filedetails['type'] = get_mimetype_description($mainfile);
293
                $filedetails['mimetype'] = $mainfile->get_mimetype();
294
                $filedetails['extension'] = strtoupper(resourcelib_get_extension($mainfile->get_filename()));
295
                // Only show type if it is not unknown.
296
                if ($filedetails['type'] === get_mimetype_description('document/unknown')) {
297
                    $filedetails['type'] = '';
298
                }
299
            } else {
300
                $filedetails['type'] = '';
301
            }
302
        }
303
        if (!empty($options['showdate'])) {
304
            if ($mainfile) {
305
                // Modified date may be up to several minutes later than uploaded date just because
306
                // teacher did not submit the form promptly. Give teacher up to 5 minutes to do it.
307
                if ($mainfile->get_timemodified() > $mainfile->get_timecreated() + 5 * MINSECS) {
308
                    $filedetails['modifieddate'] = $mainfile->get_timemodified();
309
                } else {
310
                    $filedetails['uploadeddate'] = $mainfile->get_timecreated();
311
                }
312
                if ($mainfile->get_repository_id()) {
313
                    // If main file is a reference the 'date' attribute can not be cached.
314
                    $filedetails['isref'] = true;
315
                }
316
            } else {
317
                $filedetails['uploadeddate'] = '';
318
            }
319
        }
320
    }
321
    return $filedetails;
322
}
323
 
324
/**
325
 * Gets optional details for a resource, depending on resource settings.
326
 *
327
 * Result may include the file size and type if those settings are chosen,
328
 * or blank if none.
329
 *
330
 * @param object $resource Resource table row (only property 'displayoptions' is used here)
331
 * @param object $cm Course-module table row
332
 * @param bool $showtype Whether the file type should be displayed or not (regardless the display option is enabled).
333
 * @return string Size and type or empty string if show options are not enabled
334
 */
335
function resource_get_optional_details($resource, $cm, bool $showtype = true) {
336
    global $DB;
337
 
338
    $details = '';
339
 
340
    $options = empty($resource->displayoptions) ? [] : (array) unserialize_array($resource->displayoptions);
341
    if (!empty($options['showsize']) || ($showtype && !empty($options['showtype'])) || !empty($options['showdate'])) {
342
        if (!array_key_exists('filedetails', $options)) {
343
            $filedetails = resource_get_file_details($resource, $cm);
344
        } else {
345
            $filedetails = $options['filedetails'];
346
        }
347
        $size = '';
348
        $type = '';
349
        $date = '';
350
        $langstring = '';
351
        $infodisplayed = 0;
352
        if (!empty($options['showsize'])) {
353
            if (!empty($filedetails['size'])) {
354
                $size = display_size($filedetails['size']);
355
                $langstring .= 'size';
356
                $infodisplayed += 1;
357
            }
358
        }
359
        if ($showtype && !empty($options['showtype'])) {
360
            if (!empty($filedetails['type'])) {
361
                $type = $filedetails['extension'];
362
                $langstring .= 'type';
363
                $infodisplayed += 1;
364
            }
365
        }
366
        if (!empty($options['showdate']) && (!empty($filedetails['modifieddate']) || !empty($filedetails['uploadeddate']))) {
367
            if (!empty($filedetails['modifieddate'])) {
368
                $date = get_string('modifieddate', 'mod_resource', userdate($filedetails['modifieddate'],
369
                    get_string('strftimedatetimeshort', 'langconfig')));
370
            } else if (!empty($filedetails['uploadeddate'])) {
371
                $date = get_string('uploadeddate', 'mod_resource', userdate($filedetails['uploadeddate'],
372
                    get_string('strftimedatetimeshort', 'langconfig')));
373
            }
374
            $langstring .= 'date';
375
            $infodisplayed += 1;
376
        }
377
 
378
        if ($infodisplayed > 1) {
379
            $details = get_string("resourcedetails_{$langstring}", 'resource',
380
                    (object)array('size' => $size, 'type' => $type, 'date' => $date));
381
        } else {
382
            // Only one of size, type and date is set, so just append.
383
            $details = $size . $type . $date;
384
        }
385
    }
386
 
387
    return $details;
388
}
389
 
390
/**
391
 * Gets optional file type extension for a resource, depending on resource settings.
392
 *
393
 * @param object $resource Resource table row (only property 'displayoptions' is used here)
394
 * @param object $cm Course-module table row
395
 * @return string File extension or null if showtype option is not enabled
396
 */
397
function resource_get_optional_filetype($resource, $cm): ?string {
398
    $filetype = null;
399
 
400
    $options = empty($resource->displayoptions) ? [] : (array) unserialize_array($resource->displayoptions);
401
    if (empty($options['showtype'])) {
402
        // Show type option is disabled; early return null filetype.
403
        return $filetype;
404
    }
405
 
406
    if (!array_key_exists('filedetails', $options)) {
407
        $filedetails = resource_get_file_details($resource, $cm);
408
    } else {
409
        $filedetails = $options['filedetails'];
410
    }
411
    if (!empty($filedetails['type'])) {
412
        $filetype = $filedetails['extension'];
413
    }
414
 
415
    return $filetype;
416
}
417
 
418
/**
419
 * Get resource introduction.
420
 *
421
 * @param object $resource
422
 * @param object $cm
423
 * @param bool $ignoresettings print even if not specified in modedit
424
 * @return string
425
 */
426
function resource_get_intro(object $resource, object $cm, bool $ignoresettings = false): string {
427
    $options = empty($resource->displayoptions) ? [] : (array) unserialize_array($resource->displayoptions);
428
 
429
    $extraintro = resource_get_optional_details($resource, $cm);
430
    if ($extraintro) {
431
        // Put a paragaph tag around the details
432
        $extraintro = html_writer::tag('p', $extraintro, array('class' => 'resourcedetails'));
433
    }
434
 
435
    $content = "";
436
    if ($ignoresettings || !empty($options['printintro']) || $extraintro) {
437
        $resourceintro = !empty($options['printintro']) && !html_is_blank($resource->intro);
438
 
439
        if ($resourceintro) {
440
            $content .= format_module_intro('resource', $resource, $cm->id);
441
        }
442
 
443
        if ($extraintro) {
444
            $content .= $extraintro;
445
        }
446
    }
447
 
448
    return $content;
449
}
450
 
451
/**
452
 * Print warning that instance not migrated yet.
453
 * @param object $resource
454
 * @param object $cm
455
 * @param object $course
456
 * @return void, does not return
457
 */
458
function resource_print_tobemigrated($resource, $cm, $course) {
459
    global $DB, $OUTPUT, $PAGE;
460
    $PAGE->activityheader->set_description(resource_get_intro($resource, $cm));
461
    $resource_old = $DB->get_record('resource_old', array('oldid'=>$resource->id));
462
    resource_print_header($resource, $cm, $course);
463
    echo $OUTPUT->notification(get_string('notmigrated', 'resource', $resource_old->type));
464
    echo $OUTPUT->footer();
465
    die;
466
}
467
 
468
/**
469
 * Print warning that file can not be found.
470
 * @param object $resource
471
 * @param object $cm
472
 * @param object $course
473
 * @return void, does not return
474
 */
475
function resource_print_filenotfound($resource, $cm, $course) {
476
    global $DB, $OUTPUT, $PAGE;
477
 
478
    $resource_old = $DB->get_record('resource_old', array('oldid'=>$resource->id));
479
    $PAGE->activityheader->set_description(resource_get_intro($resource, $cm));
480
    resource_print_header($resource, $cm, $course);
481
    if ($resource_old) {
482
        echo $OUTPUT->notification(get_string('notmigrated', 'resource', $resource_old->type));
483
    } else {
484
        echo $OUTPUT->notification(get_string('filenotfound', 'resource'));
485
    }
486
    echo $OUTPUT->footer();
487
    die;
488
}
489
 
490
/**
491
 * Decide the best display format.
492
 * @param object $resource
493
 * @return int display type constant
494
 */
495
function resource_get_final_display_type($resource) {
496
    global $CFG, $PAGE;
497
 
498
    if ($resource->display != RESOURCELIB_DISPLAY_AUTO) {
499
        return $resource->display;
500
    }
501
 
502
    if (empty($resource->mainfile)) {
503
        return RESOURCELIB_DISPLAY_DOWNLOAD;
504
    } else {
505
        $mimetype = mimeinfo('type', $resource->mainfile);
506
    }
507
 
508
    if (file_mimetype_in_typegroup($mimetype, 'archive')) {
509
        return RESOURCELIB_DISPLAY_DOWNLOAD;
510
    }
511
    if (file_mimetype_in_typegroup($mimetype, array('web_image', '.htm', 'web_video', 'web_audio'))) {
512
        return RESOURCELIB_DISPLAY_EMBED;
513
    }
514
 
515
    // let the browser deal with it somehow
516
    return RESOURCELIB_DISPLAY_OPEN;
517
}
518
 
519
/**
520
 * File browsing support class
521
 */
522
class resource_content_file_info extends file_info_stored {
523
    public function get_parent() {
524
        if ($this->lf->get_filepath() === '/' and $this->lf->get_filename() === '.') {
525
            return $this->browser->get_file_info($this->context);
526
        }
527
        return parent::get_parent();
528
    }
529
    public function get_visible_name() {
530
        if ($this->lf->get_filepath() === '/' and $this->lf->get_filename() === '.') {
531
            return $this->topvisiblename;
532
        }
533
        return parent::get_visible_name();
534
    }
535
}
536
 
537
function resource_set_mainfile($data) {
538
    global $DB;
539
    $fs = get_file_storage();
540
    $cmid = $data->coursemodule;
541
    $draftitemid = $data->files;
542
 
543
    $context = context_module::instance($cmid);
544
    if ($draftitemid) {
545
        $options = array('subdirs' => true, 'embed' => false);
546
        if ($data->display == RESOURCELIB_DISPLAY_EMBED) {
547
            $options['embed'] = true;
548
        }
549
        file_save_draft_area_files($draftitemid, $context->id, 'mod_resource', 'content', 0, $options);
550
    }
551
    $files = $fs->get_area_files($context->id, 'mod_resource', 'content', 0, 'sortorder', false);
552
    if (count($files) == 1) {
553
        // only one file attached, set it as main file automatically
554
        $file = reset($files);
555
        file_set_sortorder($context->id, 'mod_resource', 'content', 0, $file->get_filepath(), $file->get_filename(), 1);
556
    }
557
}