Display an image in the user notification emails of facetoface plugin

Display an image in the user notification emails of facetoface plugin

napisao/la Artem Kobylin -
Broj odgovora: 5

Hello devs,

Previously I have already asked about displaying an uploaded through a filepicker image in the browser in this post https://moodle.org/mod/forum/discuss.php?d=433320. The Davo's answer, local plugin filemanager and example of logocompact helped me to succeed in displaying an uploaded image in the browser also to not authorized users.

My current problem is to insert an uploaded image into an email so, that a recipient can see it. Honestly speaking, I thought, that I met all conditions for that, but apparently I am missing something and for some Moodle security reasons an image is still not being showed.

For testing purpose I inserted a logocompact image into an email. Attached you can find a screenshot showing a corresponding email with inserted image sent by facetoface plugin.

My code is as follows:

 --- facetoface/lib.php:

function facetoface_email_substitutions($msg, $facetofacename, $reminderperiod, $user, $data, $sessionid) {
global $CFG, $DB;

if (empty($msg)) {
return '';
}

...
    ## In configs of a facetoface instance the text of emails contains a signature placeholder 
    ## that is replaced by the signature itself 
    // in lang file $string['placeholder:signature'] = '[signature]'
$msg = str_replace(get_string('placeholder:signature', 'facetoface'), build_signature_for_emails(), $msg);

return $msg;
} function build_signature_for_emails() { $emailsignature = get_config('mod_facetoface', 'facetoface_email_signature'); $emailsignatureimg = get_signature_img(); $emailsignature = str_replace( get_string('placeholder:signatureimg', 'facetoface'), $emailsignatureimg, '<h1>Signature</h1><br>[img]' ); return $emailsignature; }
function get_signature_img() {
    global $OUTPUT;
    return html_writer::empty_tag(
        'img',
        [
            'src' => $OUTPUT->get_compact_logo_url(null, 150),
            'alt' => 'test',
            'class' => 'img-fluid'
        ]
    );
}
Thank you very much for your help in advance. 

Prilog Cancellation_email.png
U odgovoru na Artem Kobylin

Re: Display an image in the user notification emails of facetoface plugin

napisao/la Dominique Palumbo -
Slika Particularly helpful Moodlers Slika Plugin developers
Hi,
I think, that you can convert the image in base64 in the email to avoid the problem.

$path = $OUTPUT->get_compact_logo_url(null, 150);
$data = file_get_contents($path);
$base64 = 'data:image/' . $type . ';base64,' . base64_encode($data);
return '<img src="'.$base64.'" alt="'.$base64.'">";

I don't test it, but I think it can help.

Have a nice day.

Dominique.
U odgovoru na Dominique Palumbo

Re: Display an image in the user notification emails of facetoface plugin

napisao/la Dominique Palumbo -
Slika Particularly helpful Moodlers Slika Plugin developers
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>T E S T</title>
    </head>
    <body>
<?php
require_once('config.php');
$path = $OUTPUT->get_compact_logo_url(null, 150);
var_dump($path->get_path());
echo('<br>');
$data = file_get_contents('http://localhost/'.$path->get_path());
$base64 = 'data:image/png;base64,'.base64_encode($data);
echo('<img src="'.$base64.'" alt="image">"');
?>
    </body>
</html>
U odgovoru na Dominique Palumbo

Re: Display an image in the user notification emails of facetoface plugin

napisao/la Artem Kobylin -
Hello Dominique,

Thans for your advice. I tried out your idea with a small amendment:

--- facetoface/test.php

$path = $OUTPUT->get_compact_logo_url(null, 150)->__toString();
$data = file_get_contents($path);
$base64 = 'data:image/png;base64,' . base64_encode($data);
echo '<img src="' . $base64 . '" alt="Base64 img">';

I realized that file_get_contents() returns only false for all stored in Moodle files, but returns a ASCII code for an external image from google. Do you have any idea why could it be like this?
U odgovoru na Artem Kobylin

Re: Display an image in the user notification emails of facetoface plugin

napisao/la Artem Kobylin -
I struggled to get data from file_get_contents() that's why I used method of a stored_file class get_content()

--- facetoface/lib.php:

function facetoface_email_substitutions($msg, $facetofacename, $reminderperiod, $user, $data, $sessionid) {
global $CFG, $DB;

if (empty($msg)) {
return '';
}

...
    ## In configs of a facetoface instance the text of emails contains a signature placeholder 
    ## that is replaced by the signature itself 
    // in lang file $string['placeholder:signature'] = '[signature]'
$msg = str_replace(get_string('placeholder:signature', 'facetoface'), build_signature_for_emails(), $msg);

return $msg;
} function build_signature_for_emails() { ## In global facetoface settings the signature defined as a hard coded HTML ## that contains a placeholder [img] standing for a signature image $emailsignature = get_config('mod_facetoface', 'facetoface_email_signature'); $emailsignatureimg = get_signature_img();
    // in lang file $string['placeholder:signatureimg'] = '[img]'
    $emailsignature = str_replace(
        get_string('placeholder:signatureimg', 'facetoface'),
        $emailsignatureimg,
        $emailsignature
    );

    return $emailsignature;
}
function get_signature_img() {
    $systemcontext = context_system::instance();
    $fs = get_file_storage();

    if (!$files = $fs->get_area_files($systemcontext->id, 'mod_facetoface', 'signature_image')) {
        return '';
    }

    ## Only two files are expected here: one is the logo image and one is the folder
    $imgfilearr = array_filter($files, function($file) {
        return !$file->is_directory();
    });
    $imgfile = array_pop($imgfilearr);

    $base64 = 'data:image/png;base64,' . base64_encode($imgfile->get_content());

    return html_writer::img(
        $base64,
        'Logo',
        array('style' => 'max-height: 70px; margin: 15px 0;')
    );
}

The code above has been validated in the previous post I referred to at the beginning. Important things are bold.

$base64 got correct encoded data: data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAUcAAAD6CAIAAAC9CBIjAAAAA3NCSVQICAjb4U/gAAAAGXRFWHRTb2Z0d ...
Image was displayed in the browser on the test page, but unfortunately, it didn't work for an email: image was still "broken".

I gave up and made a reference on an external image, which is correctly showed in the emails.

Thanks Dominique for your help and have a nice day :)

U odgovoru na Artem Kobylin

Re: Display an image in the user notification emails of facetoface plugin

napisao/la Davo Smith -
Slika Core developers Slika Particularly helpful Moodlers Slika Peer reviewers Slika Plugin developers
If the file was inside the Moodle files API, then it is not surprising that attempting to get the file contents via file_get_contents($imageurl) wouldn't work.

If you are accessing a file via the URL, then Moodle will apply security checks to see if the user requesting the file has access to it - file_get_contents() would not include any sort of session cookie to identify the request as coming from a logged in user, so the request would be denied.