How to save filemanager input and display it to student and teacher/manager

How to save filemanager input and display it to student and teacher/manager

by Anna Heynkes -
Number of replies: 11
Hello everyone,

I'm adapting the scheduler plugin and would like to enable students to send a message to the teacher/manager when making an appointment with them.

Students can click a button to open a modal message window with a self-defined mform. The latter contains a texteditor and a filemanager. I can save and access the texteditor's content via $_POST. The drag-and-drop is also working, but now the files in the draft area of the filemanager need to be saved on submit and should be accessible / displayed to both the student who submitted them and the manager. Ideally, students should only have to click one button to book the appointment and save/send their files.

I have experimented with the functions below, but don't really know where to call (or define) them and which function or parameters would be best to use.

if ($data = $mform->get_data()) {
    // ... store or update $entry
    file_save_draft_area_files($data->attachments, $context->id, 'mod_glossary', 'attachment',
                   $entry->id, array('subdirs' => 0, 'maxbytes' => $maxbytes, 'maxfiles' => 50));
}
and:
file_postupdate_standard_filemanager($formdata, 'files', $options, $context, 'user', 'private', 0);

I'm still a beginner and would be grateful for any advice. smile

Thank you in advance

Average of ratings: -
In reply to Anna Heynkes

Re: How to save filemanager input and display it to student and teacher/manager

by Davo Smith -
Picture of Core developers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

Somewhere you should have defined a form containing the elements (i.e. the text editor, the filemanager, etc.).

So you should already have some code that looks like this:

$form = new my_form();
if ($data = $form->get_data()) {
  // Do something to save the submitted data.

// Then redirect to another page.

}

// Form not submitted, so display it.
echo $OUTPUT->header();
$form->display();
echo $OUTPUT->footer();


So you need to do the file saving inside the bit where you are processing the submitted data, as above. There is more detail on this page:
https://docs.moodle.org/dev/Using_the_File_API_in_Moodle_forms


Average of ratings: Useful (1)
In reply to Davo Smith

Re: How to save filemanager input and display it to student and teacher/manager

by Anna Heynkes -

Thank you for replying! I tried this:

$mform_simple  = new simplehtml_form('http://localhost/moodle/mod/scheduler/view.php','');      
        if($data = $mform_simple->get_data()) {
             file_save_draft_area_files($data->attachments, $context->id, 'mod_scheduler', 'attachment',
                                                           $entry->id, array('subdirs' => 0, 'maxbytes' => 0, 'maxfiles' => 30));
        }

It doesn't seem to have any effect, but I noticed that the files were saved in the db table "mdl_files", either way.
Can you tell me, whether this is where they should go and how I can access them or get their url once they're there?

(My code doesn't exactly look like the code you wrote. So far, I used javascript to display the modal window containing the mform and used an html form/$_POST to process the (texteditor) data.)

In reply to Anna Heynkes

Re: How to save filemanager input and display it to student and teacher/manager

by Davo Smith -
Picture of Core developers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

In Moodle you should never be touching $_POST at all.

If you want to get params, use the required_param() / optional_param() functions.

For processing Moodle forms, you really should try to use the proper get_data() function - when you submit the form, it should usually take you back to the same page that displayed the form in the first place, then you can process it there.

Whilst a form is being displayed, any attached files are stored in the mdl_files table, in a draft area created for that form. Before you display the form, you need to copy any existing files into the draft area (file_prepare_standard_editor and file_prepare_standard_filemanager will take care of this for you). When you submit the form and process the contents, you need to copy the files back out of the draft area and into the 'real' area (file_postupdate_standard_editor and file_postupdate_standard_filemanager will handle this for you).

The Moodle forms library is not really designed to work with javascript popups, I'm sure it is possible to get it to work that way, but you're going to have to do a lot of work to do so (especially if you're not already familiar with how to use it in the standard way).

Average of ratings: Useful (1)
In reply to Davo Smith

Re: How to save filemanager input and display it to student and teacher/manager

by Raymond Mlambo -

Hello Davo,

I am experiencing the same problems as Anna is facing. Basically, I am almost done with the activity plugin that I'm developing. The challenge that I'm facing is on saving the files and then fetching it back to be displayed in the ***/mod/pluginname/view.php page. I have no clue on how I can handle this. I've read the documentation on the File API and Forms, as well as studying other moodle plugin code e.g. Video plugin, but somehow I'm coming incredibly short. I'm seeing entries in the DB, both plugin table as well as the mdl_files table. But I cant seem to be able to get the file uploaded. Please see my code and show me where I'm going wrong:

MOD_FORM.PHP

defined('MOODLE_INTERNAL') || die();

require_once($CFG->dirroot . '/course/moodleform_mod.php');

require_once("$CFG->libdir/formslib.php");

require_once($CFG->libdir . '/filelib.php');

require_once(dirname(__FILE__) . '/lib.php');


class mod_audio_mod_form extends moodleform_mod {


    public function definition() {

        global $CFG;

        $mform = $this->_form;

        $mform->addElement('header', 'general', get_string('general', 'audio'));

        $mform->addElement('text', 'name', get_string('audioname', 'audio'), array('size' => '64'));

        if (!empty($CFG->formatstringstriptags)) {

            $mform->setType('name', PARAM_TEXT);

        } else {

            $mform->setType('name', PARAM_CLEANHTML);

        }

        $mform->addRule('name', null, 'required', null, 'client');

        $mform->addRule('name', get_string('maximumchars', '', 255), 'maxlength', 255, 'client');

        $mform->addHelpButton('name', 'audioname', 'audio');

        $mform->setDefault('name', 'Audio file name');

        // Adding the standard "intro" and "introformat" fields.

        if ($CFG->branch >= 29) {

            $this->standard_intro_elements();

        } else {

            $this->add_intro_editor();

        }

       $mform->addElement('filepicker', 'audiofile', get_string('audiofile', 'audio'), null, array('maxbytes' => $CFG->maxbytes, 'accepted_types' => 'audio'));

    $this->standard_grading_coursemodule_elements();


        // Add standard elements, common to all modules.

        $this->standard_coursemodule_elements();

        

        $this->add_action_buttons();

    }

AND THEN IN THE LIB.PHP, I HAVE THIS:

function audio_add_instance(stdClass $audio, mod_audio_mod_form $mform = null) {

    global $DB;

    $audio->timecreated = time();

    $context = context_module::instance($data->coursemodule);

    // I may have to add extra stuff in here.


    $audio->id = $DB->insert_record('audio', $audio);

    audio_grade_item_update($audio);

    return $audio->id;

}

function audio_save_draft_area_files($data) {

    $context = context_module::instance($data->coursemodule);

    if (isset($data->attachments)) {

        file_save_draft_area_files($data->attachments, $context->id, 'mod_audio', 'attachments', 0, array('subdirs' => 0, 'maxbytes' => $CFG->maxbytes, 'maxfiles' => 50));

    }

}

In reply to Raymond Mlambo

Re: How to save filemanager input and display it to student and teacher/manager

by Raymond Mlambo -

Hi guys,

I really need some assistance here. This post is getting older by the day, and my productivity has stalled. Please assist.



In reply to Raymond Mlambo

Re: How to save filemanager input and display it to student and teacher/manager

by Luis de Vasconcelos -

Does $context have anything after the $context declaration in function audio_save_draft_area_files() ?

What happens when you:

var_dump($context);
 
In reply to Davo Smith

Working example of filemanager usage

by Anna Heynkes -

Here's a commented excerpt of my working code. I hope you'll find it useful.

(If you're writing your own plugin, you need to write a function called myplugin_pluginfile() for serving files to users. See:

https://docs.moodle.org/dev/File_API#Serving_files_to_users

)

// Form settings
$context = $this->page->context;
$contextid = $context->id;
$component= 'mod_scheduler';
$filearea = 'attachment';
$itemid = 0;
$options = array('subdirs' => 0, 'maxbytes' => 0, 'areamaxbytes' => 10485760, 'maxfiles' => 50,
                              'accepted_types' => array('image', 'document', 'application/pdf', 'application/zip', 'presentation',
                              'application/vnd.openxmlformats-officedocument.presentationml.template'), 'return_types'=> FILE_INTERNAL |
                              FILE_EXTERNAL);       
// Form data
$data = new stdClass();
$schedulerid = $booker->actionurl->get_param('id');
$data->id = $schedulerid;
       
// Load any preexisting files into the draftarea
file_prepare_standard_filemanager($data, 'attachment', $options, $context, $component, $filearea, $itemid);

// Initialise mform, pass on $data and $contextid
$mform_studentcomment = new scheduler_studentcomment_form($booker->actionurl, '');
$mform_studentcomment->set_data($data);
$mform_studentcomment->set_data($contextid);
     
// Check wether the mform has just been cancelled or submitted or is to be displayed
      
//If cancelled: reload page
if ($mform_studentcomment->is_cancelled()) {
    redirect($booker->actionurl);
}
       
// If submitted: get files from filemanager
if ($data = $mform_studentcomment->get_data()) {
           
    // Get the draft itemid (Files in the drag-and-drop area are automatically saved as drafts in mdl_files even before the form is submitted.)
    $itemid = file_get_submitted_draft_itemid('attachment');
           
    if ($itemid != null) {       
        $data->attachment_filemanager = $itemid;
       
        // Save draftarea content permanently
        $data = file_postupdate_standard_filemanager($data, 'attachment', $options, $context, $component, 'studentcomment',
                                                                                            $itemid);     
        // Access the content
        $fs = get_file_storage();
        $files = $fs->get_area_files($contextid, 'mod_scheduler', 'studentcomment', $itemid, $sort = "itemid, filepath, filename",
                                                        $includedirs = true, $updatedsince = 0);  
        // Create an access url for each file and save all of them in an array
        if ($files != null) {
            $url = array();
            foreach($files as $file){
                $tmp = moodle_url::make_pluginfile_url(
                        $file->get_contextid(),
                        $file->get_component(),
                        $file->get_filearea(),  // studentcomment
                        $file->get_itemid(),  
                        $file->get_filepath(),
                        $file->get_filename(),
                        false // $forcedownload
                        );
                $url[]=$tmp;
            }
            // Save the array here ...
        }  
        // reload page
        redirect($booker->actionurl);
    }
}
// If the form was neither cancelled nor submitted: Display it       
$mform_studentcomment->display();

In reply to Davo Smith

Re: How to save filemanager input and display it to student and teacher/manager

by Edmund Evangelista -

I have the same situation. I had been reading all about this File API but could not get started because I am lost on how to start it. I know how to save the data entered by any user into a textbox/textarea and save it across related tables. But the file attachment is my problem because the sample code shown in File API are excerpts only. Can we have complete steps to store/load an attachment using filemanager of File API? As well as scripts/line of code along each steps? 

In reply to Edmund Evangelista

Re: How to save filemanager input and display it to student and teacher/manager

by Raymond Mlambo -

I really hope that someone can provide a solution for this, coz thats exactly the problem that I'm facing.

I've managed to get the file upload, saving and serving to users working in my plugins, particularly in the view.php pages. I did this through studying the code in /mod/resource and /mod/videofile. But I cant seem to get it to work, especially on a standalone form where I just want a user to upload a file and get it saved for later assessment by the teacher.

for instance, I have a separate page called "studentsfinalupload.php" where a student uploads a final document for his fellow students to look at. The form and the class instance are in this same page, and I would like to handle everything there. Some assistance would be greatly appreciated, and would really go a long way simplifying this API.


In reply to Raymond Mlambo

Re: How to save filemanager input and display it to student and teacher/manager

by Edmund Evangelista -

Raymond we have the same agenda. Mine is to develop a page that will allow teachers to upload their syllabus, store the metadata into the database using a particular course module. The syllabus uploaded should be automatically positioned on Week 0 of a particular course. I can do all the positioning of the data in Week 0 as well as store metadata in correlated tables via code behind, my only problem is to save the syllabus physically to the moodledata and reflect it back to the course using FileAPI.

The reason behind why this is done on the page I had developed is so that I could trigger a field that this particular course had uploaded a syllabus. Later on, it is easy for me to generate a report of all courses who never uploaded a syllabus.