Saving and fetching JSON file from activity module

Saving and fetching JSON file from activity module

Florian Geangoult
Vastuste arv 6

Hello everyone,

My question might seem obvious, but I am an intern and I started working with moodle recently. 

I am working on  a custom activity module and the modedit page looks as follows (The text is in French, sorry about that) : 



As you can see it's a simple form with a text field and a JSON filemanager input. My issue comes from managing the JSON file that is sent by the user. I need to save it (and I was asked not to do it using a database) and fetch it in order to feed it to my view.php and have a visual representation of the data. I believe adding the following code to lib.php should save the file to moodledata, since I've tried it via a plugin page :

if ($fromform = $mform->get_data()){

    $jsonfile = $fromform->userfile;
    file_save_draft_area_files($jsonfile, $context->id, 'mod_glossary', 'attachment',
                   0, array('subdirs' => 0, 'maxbytes' => $maxbytes, 'maxfiles' => 50));

Is that the right way to do it ? 

If it is, I'm having trouble understanding how moodle ids work, and I would want to associate the file with a course id, since it should be a unique file per course. Starting from there I would need to fetch the file associated to that id in my view.php which I'm not quite sure how to do. I have spent a lot of time reading the documentation but I am still puzzled as how to do this, hence my question.

Thanks.

Keskmine hinnang: -
Vastuses Florian Geangoult

Re: Saving and fetching JSON file from activity module

Mark Johnson
Core developers pilt Particularly helpful Moodlers pilt Peer reviewers pilt Plugin developers pilt

Files in Moodle are referenced using a unique combination of the following attributes:

  • contextid, the Moodle context the file belongs to.
  • component, the plugin or core component represented by that context.
  • filearea, a named "area" within that component for storing files of a certain type.
  • itemid, the ID of the component instance or other entity that the file belongs to.
  • filename, the name of the file.

In the example code, you saving the file uploaded to the userfile field, in the "attachment" filearea of the "mod_glossary" component, with an itemid if 0. This means that all files uploaded will be stored under the same item id, an they will be associated with the mod_glossary plugin rather than your own.

I would highly recommend reading and understanding the FIle API documentation. An example of how you might save the file against your the instance if your activity module would look like: file_save_draft_area_files($jsonfile, $context->id, 'mod_myplugin', 'jsonfiles', $plugininstance->id, ['subdirs' => 0, 'maxbytes' => $maxbytes, 'maxfiles' => 50]);

If you do only want to store one file per course, you could use $course->id instead of $plugininstance->id, but that would be a bit of an unusual approach, since different instances of the activity module could then override the file for all other instances.

Vastuses Mark Johnson

Re: Saving and fetching JSON file from activity module

Davo Smith
Core developers pilt Particularly helpful Moodlers pilt Peer reviewers pilt Plugin developers pilt
Mark, I think you might have got a little confused here.

If the $context->id is the course module context (rather than the course context), then there is no reason to use $pluginsintance->id as the item id, as the $context->id would already uniquely identify the file area against the plugin instance.

However, as the original poster asked for the file to be stored per-course, the $context should be the course context and the itemid should be 0 (because there is only 1 file area per course).

Itemids are only relevant where there are multiple file areas in a single context (e.g. in a forum where the one activity has multiple forum posts, each with their own file area).
Vastuses Davo Smith

Re: Saving and fetching JSON file from activity module

Florian Geangoult
I think I saw this reply a bit too late. My initial itemid being 0 was the right way to do it then ?

I need to set $context to be the course context, is that right ?

Thank you for your time.
Vastuses Florian Geangoult

Re: Saving and fetching JSON file from activity module

Mark Johnson
Core developers pilt Particularly helpful Moodlers pilt Peer reviewers pilt Plugin developers pilt

Thanks for clarifying that Davo, I wasn't sure if it was appropriate for an activity plugin to be storing something against the course context, but if its using its own component, that would make sense.

So yes Florian, something like file_save_draft_area_files($jsonfile, $coursecontext->id, 'mod_myplugin', 'jsonfiles', 0, ['subdirs' => 0, 'maxbytes' => $maxbytes, 'maxfiles' => 50]); would work.

Vastuses Mark Johnson

Re: Saving and fetching JSON file from activity module

Florian Geangoult
Thank you both so much, I believe it now works as intended as files are stored in the moodledata folder.

My issue is now fetching those stored files, I'm not sure which Moodle function could help me with that ?
Vastuses Mark Johnson

Re: Saving and fetching JSON file from activity module

Florian Geangoult
Thank you for your quick and detailed reply,

I have read the File API documentation quite a few times but I had trouble understanding every attribute. Thanks to your answer I now have a better grasp on these. However I am still quite not understanding what the 'contextid' refers to. I have tried to follow your exemple in my lib.php file :

function competence_add_instance($competence, mod_competence_mod_form $mform){

global $DB;

$competence->timecreated = time();
$competence->id = $DB->insert_record('competence', $competence);

if ($fromform = $mform->get_data()){
$jsonfile = $fromform->userfile;
file_save_draft_area_files($jsonfile, $context->id, 'mod_competence', 'jsonfiles',
$course->id, array('subdirs' => 0, 'maxbytes' => $maxbytes, 'maxfiles' => 50));
}
return $competence->id;

}

The following error shows up when trying to create an activity from the module

Invalid context id specified context::instance_by_id()

line 5300 of /lib/accesslib.php: coding_exception thrown
line 1155 of /lib/filelib.php: call to context::instance_by_id()
line 15 of /mod/competence/lib.php: call to file_save_draft_area_files()
line 128 of /course/modlib.php: call to competence_add_instance()
line 168 of /course/modedit.php: call to add_moduleinfo()

It is obviously a mistake on my end regarding $context->id, but with my poor knowledge of the attribute I'm not sure what the issue is.

And yes, I know it might seem a bit weird that other instances can override the file but that's what we are trying to do for now. We only intend for one instance to be used anyway (I don't know if setting a limit of module activity instances in a course is a possiblity ?)

Your help is greatly appreciated, thank you very much.