Accessing a picture uploaded through a filepicker in global plugin's settings on the view page

Accessing a picture uploaded through a filepicker in global plugin's settings on the view page

- Artem Kobylin の投稿
返信数: 2

Good day to you,

i extended a face-to-face plugin with a filepicker in global settings. I am working with moodle 3.9.

My goal is to upload a logo picture and to insert it in to a user notification emails as a part of a company's signature. For testing purposes I display an uploaded image in the browser first, on the test.php page. Unfortunately, browser tells me, that it can not find the image. 

For a comparison of the URLs, I output the logocompact using method of the core renderer_base class.

My code is as follows:

--- settings.php:

$setting = new admin_setting_configstoredfile(
'facetoface_email_signature_img',
get_string('setting:emailsignatureimg', 'facetoface'),
get_string('setting:emailsignatureimg_caption', 'facetoface'),
'signature_image',
0,
['maxfiles' => 1, 'accepted_types' => ['.jpg', '.png', '.svg']]
);
$setting->set_updatedcallback('theme_reset_all_caches');
$settings->add($setting);

--- test.php:

require_once(dirname(__FILE__, 3) . '/config.php');

global $OUTPUT;
$fs = get_file_storage();

if ($files = $fs->get_area_files($systemcontext->id, 'core', 'signature_image')) {
foreach ($files as $file) {
if ($file->is_directory()) continue;

$fileurl = moodle_url::make_pluginfile_url(
$file->get_contextid(),
$file->get_component(),
$file->get_filearea(),
$file->get_itemid(),
$file->get_filepath(),
$file->get_filename()
);
$img = html_writer::img($fileurl, 'test');
echo $img;
}
}

echo \html_writer::img($OUTPUT->get_compact_logo_url(null, 150), 'test');
The output, that I get in the browser, is shown by two screenshots attached below. Additionally I attached a screenshot showing the corresponding mdl_files records. 

I assume, the problem is the incorrect URL, which I build and that it could be fixed by using theme_get_revision(), which is used in get_compact_logo_url(). But for now all my attempts to manually integrate the output of theme_get_revision() into a URL were not successful.

Do you have any idea, why I can not access an image from the filepicker?
Thank you for you help in advance 笑顔


添付 mdl_files.png
添付 Output_in_browser_html.png
添付 Output_in_browser.png
Artem Kobylin への返信

Re: Accessing a picture uploaded through a filepicker in global plugin's settings on the view page

- Davo Smith の投稿
画像 Core developers 画像 Particularly helpful Moodlers 画像 Peer reviewers 画像 Plugin developers
You need to do 2 things:
1) you need to make sure that the 'component' is not 'core', but your own plugin (or the plugin you are extending)
2) you need to extend the plugin's PLUGINNAME_pluginfile() function in its lib.php file, so that when Moodle calls back to ask if the user is allowed to access the file requested by their browser, then it replies to allow it (i.e. you need to look at the existing code and make sure that your new 'signature_image' file area is handled by that function).
Davo Smith への返信

Re: Accessing a picture uploaded through a filepicker in global plugin's settings on the view page

- Artem Kobylin の投稿

Hello Davo

Thank you for your reply. Doing further research I came across the local plugin "Filemanager", development of that you have supported. I got through the plugin's code and found the local_filemanager_pluginfile() function there, which manages the access to plugin files. I think, I got the idea of the concept, and it worked, when I implemented it in my code.
I am writing here the changes I made and hope that this topic will help others.

Thanks again Davo for your help 笑顔.

I attached a screenshot of mdl_files with new records with the right component.

I made following changes in the code:

--- settings.php:

$setting = new admin_setting_configstoredfile(
        'mod_facetoface/facetoface_email_signature_img',
        get_string('setting:emailsignatureimg', 'facetoface'),
        get_string('setting:emailsignatureimg_caption', 'facetoface'),
        'signature_image',
        0,
        ['maxfiles' => 1, 'accepted_types' => ['.jpg', '.png', '.svg']]
);
$setting->set_updatedcallback('theme_reset_all_caches');
$settings->add($setting);

--- lib.php:

function mod_facetoface_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options=array()) {
global $DB;

if ($context->contextlevel != CONTEXT_SYSTEM) {
return false;
}
    // No require_login(), because users getting a email notification
    // are not logged in 
    if ($filearea != 'signature_image') {
return false;
}

$itemid = (int)array_shift($args);

if ($itemid != 0) {
return false;
}

$fs = get_file_storage();

$filename = array_pop($args);
if (empty($args)) {
$filepath = '/';
} else {
$filepath = '/'.implode('/', $args).'/';
}

$file = $fs->get_file($context->id, 'mod_facetoface', $filearea, $itemid, $filepath, $filename);
if (!$file) {
return false;
}

// finally send the file
send_stored_file($file, 0, 0, true, $options); // download MUST be forced - security!
}
--- test.php:

require_once(dirname(__FILE__, 3) . '/config.php');

global $OUTPUT;
$systemcontext = context_system::instance();
$fs = get_file_storage();
if ($files = $fs->get_area_files($systemcontext->id, 'mod_facetoface', 'signature_image')) {
foreach ($files as $file) {
if ($file->is_directory()) continue;

$fileurl = moodle_url::make_pluginfile_url(
$file->get_contextid(),
$file->get_component(),
$file->get_filearea(),
$file->get_itemid(),
$file->get_filepath(),
$file->get_filename()
);
$img = html_writer::img($fileurl, 'test');
echo $img;
}
}


添付 mdl_files_new_records.png
添付 Output_in_browser_html1.png
添付 Output_in_the_browser1.png