Getting an image from course format options

Getting an image from course format options

by Tony Alexander Hild -
Number of replies: 11
Hi,

I'm developing a course format that shows an image in course header.

I managed to customize the course header by overriding the course_header function.

I also included a filemanager field to the course_format_options function called headingimage.

I would like to know how generate the headingimage url from the format filearea.

I've tried in several ways but without sucess.

There is some way of creating the url like the setting_file_url function of theme?

$theme = theme_config::load('mytheme');
$theme->setting_file_url('mysetting', 'myfilearea'));


public function course_format_options($foreditform = false) {
        static $courseformatoptions = false;
        if ($courseformatoptions === false) {
            $courseconfig = get_config('moodlecourse');
            $courseformatoptions = array(
                'numsections' => array(
                    'default' => $courseconfig->numsections,
                    'type' => PARAM_INT,
                ),
                'hiddensections' => array(
                    'default' => $courseconfig->hiddensections,
                    'type' => PARAM_INT,
                ),
                'coursedisplay' => array(
                    'default' => $courseconfig->coursedisplay,
                    'type' => PARAM_INT,
                ),
                'headingimage' => array(
                    'default' => get_config('format_nead_unicentro', 'headingimage'),
                    'type' => PARAM_CLEANFILE,
                ),
                'headinginfo' => array(
                    'default' => get_config('format_nead_unicentro', 'headinginfo'),
                    'type' => PARAM_RAW,
                ),
                'teachers' => array(
                    'default' => get_config('format_nead_unicentro', 'teachers'),
                    'type' => PARAM_NOTAGS,
                ),
                'period' => array(
                    'default' => get_config('format_nead_unicentro', 'period'),
                    'type' => PARAM_NOTAGS,
                ),
            );
        }
        if ($foreditform && !isset($courseformatoptions['coursedisplay']['label'])) {
            $courseconfig = get_config('moodlecourse');
            $max = $courseconfig->maxsections;
            if (!isset($max) || !is_numeric($max)) {
                $max = 52;
            }
            $sectionmenu = array();
            for ($i = 0; $i <= $max; $i++) {
                $sectionmenu[$i] = "$i";
            }
            $courseformatoptionsedit = array(
                'numsections' => array(
                    'label' => new lang_string('numberweeks'),
                    'element_type' => 'select',
                    'element_attributes' => array($sectionmenu),
                ),
                'hiddensections' => array(
                    'label' => new lang_string('hiddensections'),
                    'help' => 'hiddensections',
                    'help_component' => 'moodle',
                    'element_type' => 'select',
                    'element_attributes' => array(
                        array(
                            0 => new lang_string('hiddensectionscollapsed'),
                            1 => new lang_string('hiddensectionsinvisible')
                        )
                    ),
                ),
                'coursedisplay' => array(
                    'label' => new lang_string('coursedisplay'),
                    'element_type' => 'select',
                    'element_attributes' => array(
                        array(
                            COURSE_DISPLAY_SINGLEPAGE => new lang_string('coursedisplay_single'),
                            COURSE_DISPLAY_MULTIPAGE => new lang_string('coursedisplay_multi')
                        )
                    ),
                    'help' => 'coursedisplay',
                    'help_component' => 'moodle',
                ),
                'headingimage' => array(
                    'label' => new lang_string('headingimage', 'format_nead_unicentro'),
                    'element_type' => 'filemanager',
                    'help' => 'headingimage',
                    'help_component' => 'format_nead_unicentro',
                ),
                'headinginfo' => array(
                    'label' => new lang_string('headinginfo', 'format_nead_unicentro'),
                    'element_type' => 'htmleditor',
                    'help' => 'headinginfo',
                    'help_component' => 'format_nead_unicentro',
                ),
                'teachers' => array(
                    'label' => new lang_string('teachers', 'format_nead_unicentro'),
                    'element_type' => 'text',
                    'help' => 'teachers',
                    'help_component' => 'format_nead_unicentro',
                ),
                'period' => array(
                    'label' => new lang_string('period', 'format_nead_unicentro'),
                    'element_type' => 'text',
                    'help' => 'period',
                    'help_component' => 'format_nead_unicentro',
                ),
            );
            $courseformatoptions = array_merge_recursive($courseformatoptions, $courseformatoptionsedit);
        }
        return $courseformatoptions;
   }

Thanks in advance,

Tony

Average of ratings: -
In reply to Tony Alexander Hild

Re: Getting an image from course format options

by Cristian Martin Nieto -

Hello Tony!

Adding the filemanager in course_format_option will only allow you to add the files to the draft area of your moodle site.

You will need to do 2 things from there. First of all, go to your update_course_format_options and save your files to a filearea from the draft area. For instance:

$context = context_course::instance($this->courseid);
$saved = file_save_draft_area_files($data->headingimage, $context->id, 'format_yourformatname',
 'headingimage', 0, array('subdirs' => 0, 'maxfiles' => 1));

That will not be enough though, in order to request your image from pluginfile with an address such as "/pluginfile.php/CONTEXTID/format_yourformatname/headingimage/0/filename.png", you will need to tell moodle how to behave when he finds that specific component. For that, you will need to create a function in your lib.php file (outside of your format class) that looks similar to this:

function format_yourformatname_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options=array()) {
    global $DB;
       
    if ($context->contextlevel != CONTEXT_COURSE) {
        return false;
    }
    
    require_login();
    if ($filearea != 'headingimage') {
        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, 'format_yourformatname', $filearea, $itemid, $filepath, $filename);
    if (!$file) {
        return false;
    }
    
    send_stored_file($file, 0, 0, $forcedownload, $options);
}
That should do the trick. By the way, I assumed you will limit the amount of files to 1, but I'm sure you will be able to adapt that code to your needs.


If someone has a better approach you're more than welcome to correct the example code pieces, but for the time being I hope that helps!

In reply to Cristian Martin Nieto

Re: Getting an image from course format options

by Tony Alexander Hild -
Thanks Cristian!

Works like a charm!

Tony
In reply to Tony Alexander Hild

Re: Getting an image from course format options

by Cristian Martin Nieto -

I just noticed a flaw in the code. If two different users try to use the filemanager field, they won't see each other's draft area. This is happening because the draft area is not prepared with file_prepare_draft_area().

I haven't been able to figure out when to invoke the file_get_submitted_draft_itemid() function to get the correct draft id and then copy the files into a shared draft area rather than having one per user.

If someone can bring some light to the subject, I would also appreciate it a lot smile

In reply to Cristian Martin Nieto

Re: Getting an image from course format options

by Gareth J Barnard -
Picture of Core developers Picture of Particularly helpful Moodlers Picture of Plugin developers

Hi Tony,

Although I don't use the course format options in this case, the Grid format manages its own set of images using the File API etc.  So feel free to browse the code: https://github.com/gjb2048/moodle-format_grid - to see how it does it in editimage.php, lib.php and renderer.php etc.

Cheers,

Gareth

In reply to Gareth J Barnard

Re: Getting an image from course format options

by Tony Alexander Hild -

Hi Gareth,

I had already looked at your code. smile

There are only a few examples of course formats, so some things takes some time to figure out.

Thanks for sharing.

In reply to Cristian Martin Nieto

Re: Getting an image from course format options

by Tony Alexander Hild -

Hi Cristian,

You're right. Only the user that saved the file can see it on the config. I'll give a try to fix this.


Thanks

In reply to Tony Alexander Hild

Re: Getting an image from course format options

by Saran Gokul -

Hi,

I am trying to create a new course format and add a header image for a course if the format selected is the new format. I followed all the steps to store the header image. The header image is getting stored as a int in the table mdl_course_format_options as name 'headerimage' and value '295861144'.

However, I am unable to display the saved image  in the course page. 

I try to output the file with a format as below to start with.

echo "<img src='".$CFG->wwwroot."/pluginfile.php/".$context->id."/format_enhancedtimeline/headerimage/295861144/2_enhamcedtimeline_banner.png'>";
But the image displays is broken. I am unable to spot the error. Please help.


Thanks in advance.

In reply to Saran Gokul

Re: Getting an image from course format options

by Richard Oelmann -
Picture of Core developers Picture of Plugin developers Picture of Testers

Is it as simple as a typo in your code

echo "<img src='".$CFG->wwwroot."/pluginfile.php/".$context->id."/format_enhancedtimeline/headerimage/295861144/2_enhamcedtimeline_banner.png'>";
enhancedtimeline and enhamcedtimeline?
In reply to Richard Oelmann

Re: Getting an image from course format options

by Saran Gokul -

Hi,

Thanks for the response. 

It was not a typo. I figured out the way to get the file displayed forming the correct url.

I am facing a different issue now. I would like to restrict the number of file uploads to 1 and accepted types as jpg or png or gif.


$options = array(
'maxfiles' => 1,
'maxbytes' => $CFG->maxbytes,
'subdirs' => 0,
'accepted_types' => array('.jpg','.gif','.png')
);

 'headerimage' => array(
'label' => new lang_string('headerimage','format_timeline'),
'element_type' => 'filemanager',
'element_attributes' => array(
),
'options' => $options,
'help' => 'headerimage',
'help_component' => 'format_timeline',

)
But this is not working. Any help please.


Thanks,

Saran



In reply to Saran Gokul

Re: Getting an image from course format options

by Cristian Martin Nieto -

Hey Saran,


Try to make your 'element_attributes' variable to look like this:

 'headerimage' => array(
     'label' => new lang_string('headerimage','format_timeline'),
     'element_type' => 'filemanager',
     'element_attributes' => array(null,
                             array(
                                   'subdirs' => 0,
                                   'maxfiles' => 1,
                                   'accepted_types' => array('.jpg', '.gif', '.png')
                             )),
     'help' => 'headerimage',
     'help_component' => 'format_timeline',

)

And remove the 'options' variable.

In reply to Cristian Martin Nieto

Re: Getting an image from course format options

by Saran Gokul -

Thanks a lot Cristian !!! Worked like a charm smile