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

by Artem Kobylin -
Number of replies: 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 smile


Attachment mdl_files.png
Attachment Output_in_browser_html.png
Attachment Output_in_browser.png
Average of ratings: -
In reply to Artem Kobylin

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

by Davo Smith -
Picture of Core developers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of 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).
In reply to Davo Smith

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

by 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 smile.

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;
}
}


Attachment mdl_files_new_records.png
Attachment Output_in_browser_html1.png
Attachment Output_in_the_browser1.png