From 6e298809e3f05c1966b61d2cfc0bfcd91ec09563 Mon Sep 17 00:00:00 2001 From: Daniel Ziegenberg Date: Fri, 25 Jul 2025 12:03:43 +0200 Subject: [PATCH] MDL-31071 core: replace deprecated file_encode_url Signed-off-by: Daniel Ziegenberg --- .../filebrowser/file_info_context_course.php | 8 +++- public/lib/filebrowser/file_info_stored.php | 8 +++- public/mod/data/field/picture/field.class.php | 15 +++++-- public/mod/folder/lib.php | 14 +++++- public/mod/forum/lib.php | 10 ++++- public/mod/glossary/lib.php | 12 ++++- .../behat/glossary_display_formats.feature | 2 + public/mod/imscp/locallib.php | 13 ++++-- public/mod/page/lib.php | 26 +++++++++-- public/mod/resource/lib.php | 14 +++++- public/mod/resource/locallib.php | 43 ++++++++++++++---- public/mod/wiki/editors/wikifiletable.php | 44 +++++++++++++++---- public/mod/wiki/locallib.php | 12 ++++- public/mod/wiki/renderer.php | 18 +++++++- 14 files changed, 202 insertions(+), 37 deletions(-) diff --git a/public/lib/filebrowser/file_info_context_course.php b/public/lib/filebrowser/file_info_context_course.php index 36d958cf019..bd609874628 100644 --- a/public/lib/filebrowser/file_info_context_course.php +++ b/public/lib/filebrowser/file_info_context_course.php @@ -25,6 +25,8 @@ defined('MOODLE_INTERNAL') || die(); +use core\url; + /** * Represents a course context in the tree navigated by {@link file_browser}. * @@ -646,7 +648,11 @@ class file_info_area_course_legacy extends file_info_stored { $path = '/'.$courseid.$filepath.$filename; - return file_encode_url($this->urlbase, $path, $forcedownload, $https); + $url = url::make_file_url($this->urlbase, $path, $forcedownload); + if ($https) { + $url->set_scheme('https'); + } + return $url->out(); } /** diff --git a/public/lib/filebrowser/file_info_stored.php b/public/lib/filebrowser/file_info_stored.php index 8c1069b65e0..820ac1a773e 100644 --- a/public/lib/filebrowser/file_info_stored.php +++ b/public/lib/filebrowser/file_info_stored.php @@ -25,6 +25,8 @@ defined('MOODLE_INTERNAL') || die(); +use core\url; + /** * Represents an actual file or folder - a row in the file table in the tree navigated by {@link file_browser}. * @@ -182,7 +184,11 @@ class file_info_stored extends file_info { } else { $path = '/'.$contextid.'/'.$component.'/'.$filearea.$filepath.$filename; } - return file_encode_url($this->urlbase, $path, $forcedownload, $https); + $url = url::make_file_url($this->urlbase, $path, $forcedownload); + if ($https) { + $url->set_scheme('https'); + } + return $url->out(); } /** diff --git a/public/mod/data/field/picture/field.class.php b/public/mod/data/field/picture/field.class.php index d62ee68da52..89a66798c8c 100644 --- a/public/mod/data/field/picture/field.class.php +++ b/public/mod/data/field/picture/field.class.php @@ -14,6 +14,9 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . +use core\output\html_writer; +use core\url; + /** * Class picture field for database activity * @@ -21,7 +24,6 @@ * @copyright 2005 Martin Dougiamas * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ - class data_field_picture extends data_field_base { var $type = 'picture'; var $previewwidth = 50; @@ -98,8 +100,15 @@ class data_field_picture extends data_field_base { } $str .= ''; diff --git a/public/mod/folder/lib.php b/public/mod/folder/lib.php index 82393fc72ea..08610f0c657 100644 --- a/public/mod/folder/lib.php +++ b/public/mod/folder/lib.php @@ -25,6 +25,8 @@ defined('MOODLE_INTERNAL') || die(); +use core\url; + /** Display folder contents on a separate page */ define('FOLDER_DISPLAY_PAGE', 0); /** Display folder contents inline in a course */ @@ -319,12 +321,20 @@ function folder_export_contents($cm, $baseurl) { $files = $fs->get_area_files($context->id, 'mod_folder', 'content', 0, 'sortorder DESC, id ASC', false); foreach ($files as $fileinfo) { - $file = array(); + $file = []; $file['type'] = 'file'; $file['filename'] = $fileinfo->get_filename(); $file['filepath'] = $fileinfo->get_filepath(); $file['filesize'] = $fileinfo->get_filesize(); - $file['fileurl'] = file_encode_url("$CFG->wwwroot/" . $baseurl, '/'.$context->id.'/mod_folder/content/'.$folder->revision.$fileinfo->get_filepath().$fileinfo->get_filename(), true); + $file['fileurl'] = url::make_webservice_pluginfile_url( + contextid: $context->id, + component: 'mod_folder', + area: 'content', + itemid: $folder->revision, + pathname: $fileinfo->get_filepath(), + filename: $fileinfo->get_filename(), + forcedownload: true + )->out(); $file['timecreated'] = $fileinfo->get_timecreated(); $file['timemodified'] = $fileinfo->get_timemodified(); $file['sortorder'] = $fileinfo->get_sortorder(); diff --git a/public/mod/forum/lib.php b/public/mod/forum/lib.php index 96dd4d06fdc..9482f99cbd6 100644 --- a/public/mod/forum/lib.php +++ b/public/mod/forum/lib.php @@ -20,6 +20,7 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ +use core\url; use mod_forum\local\entities\forum as forum_entity; defined('MOODLE_INTERNAL') || die(); @@ -2580,7 +2581,14 @@ function forum_print_attachments($post, $cm, $type) { 'style' => 'max-width: 24px; max-height: 24px; vertical-align: middle;', ] ); - $path = file_encode_url($CFG->wwwroot.'/pluginfile.php', '/'.$context->id.'/mod_forum/attachment/'.$post->id.'/'.$filename); + $path = url::make_pluginfile_url( + contextid: $context->id, + component: 'mod_forum', + area: 'attachment', + itemid: $post->id, + pathname: '/', + filename: $filename + )->out(); if ($type == 'html') { $output .= "$iconimage "; diff --git a/public/mod/glossary/lib.php b/public/mod/glossary/lib.php index 4c6226c9199..5ff2f7d2f9c 100644 --- a/public/mod/glossary/lib.php +++ b/public/mod/glossary/lib.php @@ -23,6 +23,9 @@ * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com} * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ + + use core\url; + require_once($CFG->libdir . '/completionlib.php'); define("GLOSSARY_SHOW_ALL_CATEGORIES", 0); @@ -1590,7 +1593,14 @@ function glossary_print_attachments($entry, $cm, $type=NULL, $unused = null) { $filename = $file->get_filename(); $mimetype = $file->get_mimetype(); $iconimage = $OUTPUT->pix_icon(file_file_icon($file), get_mimetype_description($file), 'moodle', array('class' => 'icon')); - $path = file_encode_url($CFG->wwwroot.'/pluginfile.php', '/'.$context->id.'/mod_glossary/attachment/'.$entry->id.'/'.$filename); + $path = url::make_pluginfile_url( + contextid: $context->id, + component: 'mod_glossary', + area: 'attachment', + itemid: $entry->id, + pathname: '/', + filename: $filename + )->out(); if ($type == 'html') { $output .= "$iconimage "; diff --git a/public/mod/glossary/tests/behat/glossary_display_formats.feature b/public/mod/glossary/tests/behat/glossary_display_formats.feature index 2a0f0ae764d..ad70705f5d3 100644 --- a/public/mod/glossary/tests/behat/glossary_display_formats.feature +++ b/public/mod/glossary/tests/behat/glossary_display_formats.feature @@ -61,6 +61,8 @@ Feature: Glossary can be set to various display formats # Confirm that glossary format is full without author style. # In this format, the image link should exist and author's name should not be visible. Then "gd-logo.png" "link" should exist + And following "gd-logo.png" should download a file that: + | has mimetype | image/png | And I should not see "by Admin User" And ".fullwithoutauthor" "css_element" should exist diff --git a/public/mod/imscp/locallib.php b/public/mod/imscp/locallib.php index 5509cc0ef30..eef037e7a59 100644 --- a/public/mod/imscp/locallib.php +++ b/public/mod/imscp/locallib.php @@ -24,6 +24,8 @@ defined('MOODLE_INTERNAL') || die(); +use core\url; + require_once("$CFG->dirroot/mod/imscp/lib.php"); require_once("$CFG->libdir/filelib.php"); require_once("$CFG->libdir/resourcelib.php"); @@ -68,9 +70,14 @@ function imscp_htmllize_item($item, $imscp, $cm) { $url = $item['href']; } else { $context = context_module::instance($cm->id); - $urlbase = "$CFG->wwwroot/pluginfile.php"; - $path = '/'.$context->id.'/mod_imscp/content/'.$imscp->revision.'/'.$item['href']; - $url = file_encode_url($urlbase, $path, false); + $url = url::make_pluginfile_url( + contextid: $context->id, + component: 'mod_imscp', + area: 'content', + itemid: $imscp->revision, + pathname: '/', + filename: $item['href'] + )->out(); } $result = "
  • ".$item['title'].''; } else { diff --git a/public/mod/page/lib.php b/public/mod/page/lib.php index 8f49b1102a2..edbc32b9a68 100644 --- a/public/mod/page/lib.php +++ b/public/mod/page/lib.php @@ -23,6 +23,8 @@ defined('MOODLE_INTERNAL') || die; +use core\url; + /** * List of features supported in Page module * @param string $feature FEATURE_xx constant for requested feature @@ -409,12 +411,20 @@ function page_export_contents($cm, $baseurl) { $fs = get_file_storage(); $files = $fs->get_area_files($context->id, 'mod_page', 'content', 0, 'sortorder DESC, id ASC', false); foreach ($files as $fileinfo) { - $file = array(); + $file = []; $file['type'] = 'file'; $file['filename'] = $fileinfo->get_filename(); $file['filepath'] = $fileinfo->get_filepath(); $file['filesize'] = $fileinfo->get_filesize(); - $file['fileurl'] = file_encode_url("$CFG->wwwroot/" . $baseurl, '/'.$context->id.'/mod_page/content/'.$page->revision.$fileinfo->get_filepath().$fileinfo->get_filename(), true); + $file['fileurl'] = url::make_webservice_pluginfile_url( + contextid: $context->id, + component: 'mod_page', + area: 'content', + itemid: $page->revision, + pathname: $fileinfo->get_filepath(), + filename: $fileinfo->get_filename(), + forcedownload: true + )->out(); $file['timecreated'] = $fileinfo->get_timecreated(); $file['timemodified'] = $fileinfo->get_timemodified(); $file['sortorder'] = $fileinfo->get_sortorder(); @@ -431,12 +441,20 @@ function page_export_contents($cm, $baseurl) { // page html conent $filename = 'index.html'; - $pagefile = array(); + $pagefile = []; $pagefile['type'] = 'file'; $pagefile['filename'] = $filename; $pagefile['filepath'] = '/'; $pagefile['filesize'] = 0; - $pagefile['fileurl'] = file_encode_url("$CFG->wwwroot/" . $baseurl, '/'.$context->id.'/mod_page/content/' . $filename, true); + $pagefile['fileurl'] = url::make_webservice_pluginfile_url( + contextid: $context->id, + component: 'mod_page', + area: 'content', + itemid: null, + pathname: '/', + filename: $filename, + forcedownload: true + )->out(); $pagefile['timecreated'] = null; $pagefile['timemodified'] = $page->timemodified; // make this file as main file diff --git a/public/mod/resource/lib.php b/public/mod/resource/lib.php index a81216293e0..15073a10460 100644 --- a/public/mod/resource/lib.php +++ b/public/mod/resource/lib.php @@ -23,6 +23,8 @@ defined('MOODLE_INTERNAL') || die; +use core\url; + /** * List of features supported in Resource module * @param string $feature FEATURE_xx constant for requested feature @@ -447,12 +449,20 @@ function resource_export_contents($cm, $baseurl) { $files = $fs->get_area_files($context->id, 'mod_resource', 'content', 0, 'sortorder DESC, id ASC', false); foreach ($files as $fileinfo) { - $file = array(); + $file = []; $file['type'] = 'file'; $file['filename'] = $fileinfo->get_filename(); $file['filepath'] = $fileinfo->get_filepath(); $file['filesize'] = $fileinfo->get_filesize(); - $file['fileurl'] = file_encode_url("$CFG->wwwroot/" . $baseurl, '/'.$context->id.'/mod_resource/content/'.$resource->revision.$fileinfo->get_filepath().$fileinfo->get_filename(), true); + $file['fileurl'] = url::make_webservice_pluginfile_url( + contextid: $context->id, + component: 'mod_resource', + area: 'content', + itemid: $resource->revision, + pathname: $fileinfo->get_filepath(), + filename: $fileinfo->get_filename(), + forcedownload: true + )->out(); $file['timecreated'] = $fileinfo->get_timecreated(); $file['timemodified'] = $fileinfo->get_timemodified(); $file['sortorder'] = $fileinfo->get_sortorder(); diff --git a/public/mod/resource/locallib.php b/public/mod/resource/locallib.php index 1936b7d8304..9a77d28bfd5 100644 --- a/public/mod/resource/locallib.php +++ b/public/mod/resource/locallib.php @@ -25,6 +25,8 @@ defined('MOODLE_INTERNAL') || die; +use core\url; + require_once("$CFG->libdir/filelib.php"); require_once("$CFG->libdir/resourcelib.php"); require_once("$CFG->dirroot/mod/resource/lib.php"); @@ -133,8 +135,14 @@ function resource_display_frame($resource, $cm, $course, $file) { } else { $config = get_config('resource'); $context = context_module::instance($cm->id); - $path = '/'.$context->id.'/mod_resource/content/'.$resource->revision.$file->get_filepath().$file->get_filename(); - $fileurl = file_encode_url($CFG->wwwroot.'/pluginfile.php', $path, false); + $fileurl = url::make_pluginfile_url( + contextid: $context->id, + component: 'mod_resource', + area: 'content', + itemid: $resource->revision, + pathname: $file->get_filepath(), + filename: $file->get_filename() + )->out(); $navurl = "$CFG->wwwroot/mod/resource/view.php?id=$cm->id&frameset=top"; $title = strip_tags(format_string($course->shortname.': '.$resource->name)); $framesize = $config->framesize; @@ -169,8 +177,14 @@ function resource_get_clicktoopen($file, $revision, $extra='') { global $CFG; $filename = $file->get_filename(); - $path = '/'.$file->get_contextid().'/mod_resource/content/'.$revision.$file->get_filepath().$file->get_filename(); - $fullurl = file_encode_url($CFG->wwwroot.'/pluginfile.php', $path, false); + $fullurl = url::make_pluginfile_url( + contextid: $file->get_contextid(), + component: 'mod_resource', + area: 'content', + itemid: $revision, + pathname: $file->get_filepath(), + filename: $filename + )->out(); $string = get_string('clicktoopen2', 'resource', "$filename"); @@ -184,8 +198,15 @@ function resource_get_clicktodownload($file, $revision) { global $CFG; $filename = $file->get_filename(); - $path = '/'.$file->get_contextid().'/mod_resource/content/'.$revision.$file->get_filepath().$file->get_filename(); - $fullurl = file_encode_url($CFG->wwwroot.'/pluginfile.php', $path, true); + $fullurl = url::make_pluginfile_url( + $file->get_contextid(), + 'mod_resource', + 'content', + $revision, + $file->get_filepath(), + $filename, + true + )->out(); $string = get_string('clicktodownload', 'resource', "$filename"); @@ -212,8 +233,14 @@ function resource_print_workaround($resource, $cm, $course, $file) { echo '
    '; switch (resource_get_final_display_type($resource)) { case RESOURCELIB_DISPLAY_POPUP: - $path = '/'.$file->get_contextid().'/mod_resource/content/'.$resource->revision.$file->get_filepath().$file->get_filename(); - $fullurl = file_encode_url($CFG->wwwroot.'/pluginfile.php', $path, false); + $fullurl = url::make_pluginfile_url( + contextid: $file->get_contextid(), + component: 'mod_resource', + area: 'content', + itemid: $resource->revision, + pathname: $file->get_filepath(), + filename: $file->get_filename() + )->out(); $options = empty($resource->displayoptions) ? [] : (array) unserialize_array($resource->displayoptions); $width = empty($options['popupwidth']) ? 620 : $options['popupwidth']; $height = empty($options['popupheight']) ? 450 : $options['popupheight']; diff --git a/public/mod/wiki/editors/wikifiletable.php b/public/mod/wiki/editors/wikifiletable.php index 37f3f655a8d..96577623dc4 100644 --- a/public/mod/wiki/editors/wikifiletable.php +++ b/public/mod/wiki/editors/wikifiletable.php @@ -26,6 +26,8 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ +use core\url; + require_once('HTML/QuickForm/element.php'); require_once($CFG->dirroot.'/lib/filelib.php'); @@ -117,22 +119,48 @@ class MoodleQuickForm_wikifiletable extends HTML_QuickForm_element { } $checkbox .= " />"; - //actions + // Get Actions. $icon = file_file_icon($file); - $file_url = file_encode_url($CFG->wwwroot.'/pluginfile.php', "/{$this->_contextid}/mod_wiki/attachments/{$this->_fileareaitemid}/".$file->get_filename()); + $filename = $file->get_filename(); + $fileurl = url::make_pluginfile_url( + contextid: $this->_contextid, + component: 'mod_wiki', + area: 'attachments', + itemid: $this->_fileareaitemid, + pathname: '/', + filename: $filename + )->out(); - $action_icons = ""; - if(!empty($tags['attach'])) { - $action_icons .= "printInsertTags($tags['attach'], $file->get_filename())." title=\"".get_string('attachmentattach', 'wiki')."\">".$OUTPUT->pix_icon($icon, "Attach").""; //TODO: localize + $actionicons = ""; + if (!empty($tags['attach'])) { + $actionicons .= 'printInsertTags($tags['attach'], $filename); + $actionicons .= ' title="'; + $actionicons .= get_string('attachmentattach', 'wiki'); + $actionicons .= '">'; + $actionicons .= $OUTPUT->pix_icon($icon, "Attach"); + $actionicons .= ''; } - $action_icons .= "  printInsertTags($tags['link'], $file_url)." title=\"".get_string('attachmentlink', 'wiki')."\">".$OUTPUT->pix_icon($icon, "Link").""; + $actionicons .= '  printInsertTags($tags['link'], $fileurl); + $actionicons .= ' title="'; + $actionicons .= get_string('attachmentlink', 'wiki'); + $actionicons .= '">'; + $actionicons .= $OUTPUT->pix_icon($icon, 'Link'); + $actionicons .= ''; if (file_mimetype_in_typegroup($file->get_mimetype(), 'web_image')) { - $action_icons .= "  printInsertTags($tags['image'], $file->get_filename())." title=\"".get_string('attachmentimage', 'wiki')."\">".$OUTPUT->pix_icon($icon, "Image").""; //TODO: localize + $actionicons .= '  printInsertTags($tags['image'], $filename); + $actionicons .= 'title="'; + $actionicons .= get_string('attachmentimage', 'wiki'); + $actionicons .= '">'; + $actionicons .= $OUTPUT->pix_icon($icon, 'Image'); + $actionicons .= ''; } - $htmltable->data[] = array($checkbox, ''.$file->get_filename().'', $action_icons); + $htmltable->data[] = [$checkbox, '' . $filename . '', $actionicons]; } } diff --git a/public/mod/wiki/locallib.php b/public/mod/wiki/locallib.php index b06909e896e..1fad47888e6 100644 --- a/public/mod/wiki/locallib.php +++ b/public/mod/wiki/locallib.php @@ -34,6 +34,8 @@ defined('MOODLE_INTERNAL') || die(); +use core\url; + require_once($CFG->dirroot . '/mod/wiki/lib.php'); require_once($CFG->dirroot . '/mod/wiki/parser/parser.php'); require_once($CFG->libdir . '/filelib.php'); @@ -1487,7 +1489,15 @@ function wiki_print_upload_table($context, $filearea, $fileitemid, $deleteupload $checkbox .= " />"; - $htmltable->data[] = array($checkbox, '' . $file->get_filename() . '', ""); + $url = url::make_pluginfile_url( + contextid: $context->id, + component: 'wiki_upload', + area: '', + itemid: $fileitemid, + pathname: '/', + filename: $file->get_filename() + ); + $htmltable->data[] = [$checkbox, '' . $file->get_filename() . '', ""]; } } diff --git a/public/mod/wiki/renderer.php b/public/mod/wiki/renderer.php index 514d2794e95..69b01aa8681 100644 --- a/public/mod/wiki/renderer.php +++ b/public/mod/wiki/renderer.php @@ -23,6 +23,10 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ +use core\output\html_writer; +use core\output\plugin_renderer_base; +use core\url; + defined('MOODLE_INTERNAL') || die(); class mod_wiki_renderer extends plugin_renderer_base { @@ -526,10 +530,20 @@ class mod_wiki_renderer extends plugin_renderer_base { $result .= '
  • '.$image.' '.s($subdir['dirname']).'
    '.$this->htmllize_tree($tree, $subdir).'
  • '; } foreach ($dir['files'] as $file) { - $url = file_encode_url("$CFG->wwwroot/pluginfile.php", '/'.$tree->context->id.'/mod_wiki/attachments/' . $tree->subwiki->id . '/'. $file->get_filepath() . $file->get_filename(), true); $filename = $file->get_filename(); + $url = url::make_pluginfile_url( + contextid: $tree->context->id, + component: 'mod_wiki', + area: 'attachments', + itemid: $tree->subwiki->id, + pathname: $file->get_filepath(), + filename: $filename, + forcedownload: true + ); $image = $this->output->pix_icon(file_file_icon($file), $filename, 'moodle', array('class'=>'icon')); - $result .= '
  • '.$image.' '.html_writer::link($url, $filename).'
  • '; + $result .= '
  • '; + $result .= '
    ' . $image . ' ' . html_writer::link($url->out(), $filename) . '
    '; + $result .= '
  • '; } $result .= '';