please explain admin_setting_configstoredfile()

please explain admin_setting_configstoredfile()

by Danny Wahl -
Number of replies: 13

I've looked through simple at how the logo is added and called and tried to replicate it in my own theme but I'm always getting a "file not found" error.  The only thing(s) I've changed are:

setting name (shouldn't matter)

filearea (probably what's wrong)

the reason I changed it is because there was a lot of hard-coded 'logo' strings/calls throughout and I wanted to dissect it to make sure I properly understood it.  Now I'm guessing that maybe logo is a valid filearea value but anything else is not?

so if I do this:

$setting = $PAGE->theme->setting_file_url('setting', 'setting'); echo $setting;

I get this return but it's a file not found error (but seems liek it should be right):

//localhost/moodle/moodle/pluginfile.php/1/theme_themename/setting/-1/this.png
Average of ratings: -
In reply to Danny Wahl

Re: please explain admin_setting_configstoredfile()

by Mary Evans -
Picture of Core developers Picture of Documentation writers Picture of Peer reviewers Picture of Plugin developers Picture of Testers

Danny,

It's too complex for me to understand let alone tell you. However I am sure Gareth will be able to explain in more detail.

To understand this fully, you would need to read the discussion in MDL-35434 and related bug fixes in MDL-39129 and MDL-39178

Cheers

Mary

In reply to Mary Evans

Re: please explain admin_setting_configstoredfile()

by Danny Wahl -

Thanks Mary, you pointed me in the right direction.  I was missing the magic function

theme_themename_pluginfile()

from my themelib.  I had seen it in your commit to simple, but didn't see anywhere where it was called.  I thought it was leftovers ;)

https://github.com/thedannywahl/moodle-theme-settings/tree/admin_setting_configstoredfile

In reply to Danny Wahl

Re: please explain admin_setting_configstoredfile()

by tim st.clair -
Picture of Plugin developers

well I sure don't get it, and your github is pretty confusing in its variable naming. "admin_setting_" what? I'd like to know if it's possible to store more than 1 file per theme, and how to do that. so I can have a banners file area, and just get the urls like this:

$image1 = setting_file_url("image1", "banners");

$image2 = setting_file_url("image2", "banners");

$image3 = setting_file_url("image3", "banners");

doesn't work for me; they all seem to have the same url.

also, I don't understand "filearea" properly. do I need do "get it" or can I set it to my theme names or any old name I like for the grouping of files I want to insert. does it matter where is the file actually stored? settings_file_url says the url is /$syscontext->id/$component/$filearea/$itemid".$filepath, so that means /themes/my_theme/filearea/4439349/image1.png right? is this hidden away in the moodle data?

I don't want to use them in CSS so I haven't implemented a process_css. The "magic" function confounds me because it seems to be only capable of serving a single file; that is 

return $theme->setting_file_serve('admin_setting_configstoredfile', $args, $forcedownload, $options);

is it possible to serve more than 1 file? If not, then this function is next to useless for me.

I was thinking about using this in my theme (in layout/general.php) and not implementing the "magic" function at all, but haven't had luck so far.

$theme = theme_config::load('mytheme');
$image1 = $theme->setting_file_serve('admin_setting_image1', $args, $forcedownload, $options);
$image2 = $theme->setting_file_serve('admin_setting_image2', $args, $forcedownload, $options);
$image3 = $theme->setting_file_serve('admin_setting_image3', $args, $forcedownload, $options);

but am not sure what $args should be ($forcedownload would be false, $options is probably a blank array, reading outputlib.php hasn't helped me understand the point of $args at all). 

 

In reply to tim st.clair

Re: please explain admin_setting_configstoredfile()

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

Dear all,

I will admit that being a recent addition that 'admin_setting_configstoredfile' is not documented well anywhere yet, but it does support multiple images etc.  So, using Julian's Essential theme as an example - https://github.com/moodleman/moodle-theme_essential :

So, in settings.php define your images:

    $name = 'theme_essential/slide1image';
    $title = get_string('slide1image', 'theme_essential');
    $description = get_string('slide1imagedesc', 'theme_essential');
    $setting = new admin_setting_configstoredfile($name, $title, $description, 'slide1image');
    $setting->set_updatedcallback('theme_reset_all_caches');
    $settings->add($setting);

...

    $name = 'theme_essential/slide2image';
    $title = get_string('slide2image', 'theme_essential');
    $description = get_string('slide2imagedesc', 'theme_essential');
    $setting = new admin_setting_configstoredfile($name, $title, $description, 'slide2image');
    $setting->set_updatedcallback('theme_reset_all_caches');
    $settings->add($setting);

...

    $name = 'theme_essential/slide3image';
    $title = get_string('slide3image', 'theme_essential');
    $description = get_string('slide3imagedesc', 'theme_essential');
    $setting = new admin_setting_configstoredfile($name, $title, $description, 'slide3image');
    $setting->set_updatedcallback('theme_reset_all_caches');
    $settings->add($setting);

...

    $name = 'theme_essential/slide4image';
    $title = get_string('slide4image', 'theme_essential');
    $description = get_string('slide4imagedesc', 'theme_essential');
    $setting = new admin_setting_configstoredfile($name, $title, $description, 'slide4image');
    $setting->set_updatedcallback('theme_reset_all_caches');
    $settings->add($setting);

 

 Then in 'lib.php' there are two processes:

function essential_process_css($css, $theme) {

...
    // Set Slide Images.
    $setting = 'slide1image';
    // Creates the url for image file which is then served up by 'theme_essential_pluginfile' below.
    $slideimage = $theme->setting_file_url($setting, $setting);
    $css = essential_set_slideimage($css, $slideimage, $setting);

    $setting = 'slide2image';
    $slideimage = $theme->setting_file_url($setting, $setting);
    $css = essential_set_slideimage($css, $slideimage, $setting);

    $setting = 'slide3image';
    $slideimage = $theme->setting_file_url($setting, $setting);
    $css = essential_set_slideimage($css, $slideimage, $setting);

    $setting = 'slide4image';
    $slideimage = $theme->setting_file_url($setting, $setting);
    $css = essential_set_slideimage($css, $slideimage, $setting);

    return $css;
}
function essential_set_slideimage($css, $slideimage, $setting) {
    global $OUTPUT;
    $tag = 'setting:'.$setting.'';
    $replacement = $slideimage;
    if (is_null($replacement)) {
        // Get default image from themes 'images' folder of the name in $setting.
        $replacement = $OUTPUT->pix_url('images/'.$setting, 'theme');
    }
    $css = str_replace($tag, $replacement, $css);
    return $css;
}

(assume double '[' for the settings as TinyMCE seems to be dropping them) and

function theme_essential_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options = array()) {
    if ($context->contextlevel == CONTEXT_SYSTEM and $filearea === 'logo') {
        $theme = theme_config::load('essential');
        return $theme->setting_file_serve('logo', $args, $forcedownload, $options);
    } else if ($context->contextlevel == CONTEXT_SYSTEM and $filearea === 'slide1image') {
        $theme = theme_config::load('essential');
        return $theme->setting_file_serve('slide1image', $args, $forcedownload, $options);
    } else if ($context->contextlevel == CONTEXT_SYSTEM and $filearea === 'slide2image') {
        $theme = theme_config::load('essential');
        return $theme->setting_file_serve('slide2image', $args, $forcedownload, $options);
    } else if ($context->contextlevel == CONTEXT_SYSTEM and $filearea === 'slide3image') {
        $theme = theme_config::load('essential');
        return $theme->setting_file_serve('slide3image', $args, $forcedownload, $options);
    } else if ($context->contextlevel == CONTEXT_SYSTEM and $filearea === 'slide4image') {
        $theme = theme_config::load('essential');
        return $theme->setting_file_serve('slide4image', $args, $forcedownload, $options);
    } else {
        send_file_not_found();
    }
}

Then in the css (in this example 'slides.css'):

.da-slide .da-img1 {
	background: url(setting:slide1image) no-repeat 0 0;
}

.da-slide .da-img2 {
	background: url(setting:slide2image) no-repeat 0 0;
}

.da-slide .da-img3 {
	background: url(setting:slide3image) no-repeat 0 0;
}

.da-slide .da-img4 {
	background: url(setting:slide4image) no-repeat 0 0;
}

Assume double '[' for the settings as TinyMCE seems to be dropping them.

So what is going on is that in 'settings.php' you define the setting with the filearea of 'slideXimage' and the setting name of 'slideXimage' being the postfix bit if 'theme_essential/slideXimage'.  Then the process css code in lib.php generates URL's that refer to 'pluginfile.php' with some parameters for the image.  Then when the web page loads the browser gets the images by calling 'pluginfile.php' which in turn finds your 'theme_essential_pluginfile' function which then serves up the file from the storage area using the 'setting_file_serve' method.  Confusion may arise from the name of the setting and the name of the file area being the same in this example (i.e. the same parameter to 'setting_file_url' but in reality its setting and filearea - order not sure), but to explain that I would need to look up the function documentation in the files and this post is from memory!  But I hope it helps to get you going.

Cheers,

Gareth

Average of ratings: Useful (1)
In reply to Gareth J Barnard

Re: please explain admin_setting_configstoredfile()

by tim st.clair -
Picture of Plugin developers

Ok, thanks for the clarity Gareth! This answers what I was finding confusing - that $filearea isn't a "folder that contains multiple uploads", rather a "naming container for the single upload instance". I was already heading in that direction anyway.

So, just to state inside this thread (in case anyone else comes across it) you can also get access to the files in the php pages (e.g. layout/*.php), e.g.

$termspdf = $PAGE->theme->setting_file_url('terms', 'terms');
html_writer::tag('a', '', array('href'=>$termspdf));

p.s. Any reason you are clearing the theme cache before every settings addition? 

 

 

In reply to tim st.clair

Re: please explain admin_setting_configstoredfile()

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

Dear Tim,

RE: Any reason you are clearing the theme cache before every settings addition?

Because of the setting URL in the CSS I think is cached and therefore needs regenerating when the setting changes.  But that does ask the question if the URL actually changes?  Needs investigating.

Cheers,

Gareth

In reply to tim st.clair

Re: please explain admin_setting_configstoredfile()

by Mary Evans -
Picture of Core developers Picture of Documentation writers Picture of Peer reviewers Picture of Plugin developers Picture of Testers

Hi Tim,

I have not read Gareth's comments as they are probably answering your questions and not related to what I am going to ask you in this comment.

Can you say is simple language what it is you are wanting to do?

For instance, are you wanting to have a rotating banner in your Moodle site header?

Mary

In reply to Mary Evans

Re: please explain admin_setting_configstoredfile()

by tim st.clair -
Picture of Plugin developers

i'd like to have left, right header images on my theme that are easily configurable without ftp access, and multiple (unlimited banner images configured through the theme), plus a link to a pdf terms and conditions, editable through the theme.

In reply to tim st.clair

Re: please explain admin_setting_configstoredfile()

by Mary Evans -
Picture of Core developers Picture of Documentation writers Picture of Peer reviewers Picture of Plugin developers Picture of Testers

That sounds pretty easy to do.

Have you read all the tutorials found via the link at the top of this Forum page?

The ones relevant to you are listed below:

  1. http://docs.moodle.org/dev/Themes
  2. http://docs.moodle.org/dev/Creating_a_theme_settings_page
  3. http://docs.moodle.org/dev/Using_images_in_a_theme
  4. http://docs.moodle.org/dev/Overriding_a_renderer

Hope this helps? smile

Mary

In reply to Mary Evans

Re: please explain admin_setting_configstoredfile()

by tim st.clair -
Picture of Plugin developers

indeed I have. But I was really looking for a way that the user (not the theme developer) to be able to change aspects of the theme without having ftp access to the theme folder itself, and certainly without php skills. That means giving them a way to upload multiple document types from the theme settings page. Cheers for the links as reference though.

In reply to tim st.clair

Re: please explain admin_setting_configstoredfile()

by Mary Evans -
Picture of Core developers Picture of Documentation writers Picture of Peer reviewers Picture of Plugin developers Picture of Testers

There is nothing stopping anyone from uploading images to a Moodle site you do not need extra settings to do that. Same goes for a PDF that can be loaded for a users desttop and embedded in a RESOURCE page and then linked to from the custommenu in Admin... > Appearance > Themes > Theme settings.

What you do need settings for are the URLs that add an image that is part of the theme, be it directly in to a layout file like general.php or as a CSS background. All that is covered in the Tutorials.

The reason that you can only upload one image per setting for a logo or a header banner is that only one image is required in other words a ONE to ONE scenario and not a MANY to ONE. If you need 100 banner images you would need to set up 100 settings to match, same too for URLs.

Unless you know sufficient PHP yourself so you can change the way Moodle works in this regard, then you can only use what is available.

The alternative is to use a form that allows the use of a file picker where multiple images can be uploaded. An instance of that can be seen in the AADAR theme. I think this is quite an interesting theme.

Hope all this helps?

Mary

In reply to Mary Evans

please explain admin_setting_configstoredfile()

by Ramesh T -

Hi ,

 I would like to add options using check box in admin setings page. Is that possible to have check box in the settings page if yes please guide me to do that then.