Q:

Subir archivos y carpetas en Moodle

Necesito subir archivos y carpetas dentro de un curso de Moodle, estos archivos provienen de un zip. He estado buscando y he encontrado cómo subir archivos, lo he probado y consigo subir archivos correctamente en la base de datos y en el repositorio de archivos de Moodle, pero estos archivos no se muestran en el curso cuando entro vía web.
El código que estoy probando es el siguiente:
$packer = get_file_packer('application/zip');
$files = $packer->extract_to_pathname($archivo_zip, $carpeta_unzip );

foreach($files as $path => $status){
    $fs = get_file_storage();                                   
    $context = context_course::instance($courseid);

    $filename = basename($path);
    $path_directory = "/" . str_replace($filename, "", $path);

    $author = $DB->get_record('user', array('id'=>$userid ), '*', MUST_EXIST);

    $file_record = new stdClass;
    $file_record->component = 'mod_folder';     //mod_resource  
    $file_record->contextid = $context->id;         
    $file_record->userid    = $userid ;                 
    $file_record->filearea  = 'content';            //draft, attachment
    $file_record->filename = $filename;             
    $file_record->filepath  = $path_directory;      
    $file_record->itemid    = 0;                
    $file_record->author    = fullname($author);
    $file_record->license   = $CFG->sitedefaultlicense;
    $file_record->source    = $filename;            
    //$file_record->timecreated    = time();            
    //$file_record->timemodified    = time();           

    $existingfile = $fs->file_exists($file_record->contextid, $file_record->component, $file_record->filearea,
    $file_record->itemid, $file_record->filepath, $file_record->filename);

    if ($existingfile) {
        //throw new file_exception('filenameexist');
    } else {
        $stored_file = $fs->create_file_from_pathname($file_record, $path_upload);
    }
}

He probado a subir archivos y carpetas manualmente desde la web de Moodle y me he dado cuenta que las carpetas hay veces que se crean en otra tabla llamada mdl_folder y otras veces en la misma tabla que los archivos, mdl_files. No sé cual es la mejor forma de crear y relacionar las carpetas con los archivos para que después se puedan ver correctamente desde la web
Si alguien conoce cómo hacerlo o tiene algún ejemplo o documentación que me pueda servir, será una gran ayuda para mi.

A:

He encontrado una solución que me funciona, no se si es la más adecuada o no, si alguien le puede echar un vistazo y decirme si es correcto o no, o que cambios podría hacer estaría agradecido.
La solución que encontrado es la siguiente:

Crear o recuperar la carpeta que contendrá todos los archivos.
Crear cada uno de los archivos.

Código:
 $packer = get_file_packer('application/zip');
    $files = $packer->extract_to_pathname($archivo_zip, $carpeta_unzip );

    foreach($files as $path => $status){
        $fs = get_file_storage();    

        $folder = get_folder($courseid, 'Prueba Upload');   

        $filename = basename($path);
        $path_directory = "/" . str_replace($filename, "", $path);

        $author = $DB->get_record('user', array('id'=>$userid ), '*', MUST_EXIST);

        $file_record = new stdClass;
        $file_record->component = 'mod_folder';     //mod_resource  
        $file_record->contextid = $folder->id;         
        $file_record->userid    = $userid ;                 
        $file_record->filearea  = 'content';            //draft, attachment
        $file_record->filename = $filename;             
        $file_record->filepath  = $path_directory;      
        $file_record->itemid    = 0;                
        $file_record->author    = fullname($author);
        $file_record->license   = $CFG->sitedefaultlicense;
        $file_record->source    = $filename;            
        //$file_record->timecreated    = time();            
        //$file_record->timemodified    = time();           

        $existingfile = $fs->file_exists($file_record->contextid, $file_record->component, $file_record->filearea,
        $file_record->itemid, $file_record->filepath, $file_record->filename);

        if ($existingfile) {
            //throw new file_exception('filenameexist');
        } else {
            $stored_file = $fs->create_file_from_pathname($file_record, $path_upload);
        }
    }

Y la función para crear la carpeta que contendrá los archivos es la siguiente:
/**
 * Devuelve una carpeta o la crea.
 *
 * @param $courseid id del curso.
 * @param $resource_name nombre de la carpeta.
 *
 * @return context de la carpeta
 */
function get_folder($courseid, $resource_name) {
    global $DB, $CFG;

    //Comprobamos si la carpeta ya existe ya existe

    $sql = "SELECT cm.id as cmid FROM {course_modules} cm, {folder} res
        WHERE res.name = '" . $resource_name . "'
        AND cm.course = " . $courseid . "
        AND cm.instance = res.id";

    if (! $coursemodule = $DB->get_record_sql($sql)) {      
        require_once($CFG->dirroot.'/course/lib.php');

        echo "\tCreate new folder\n";

        $course = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST);

        // get module id
        $module = $DB->get_record('modules', array('name' => 'folder'), '*', MUST_EXIST);

        // get course section
        /*course_create_sections_if_missing($course->id, 0);
        $modinfo = get_fast_modinfo($course->id);
        $cw = $modinfo->get_section_info(0);

        echo "section id: " . $cw->id;*/

        $sectionid = $DB->get_record('course_sections', array('course' => $course->id, 'name' => 'Recursos'), '*', MUST_EXIST);

        $folder_data = new stdClass();
        $folder_data->course = $course->id;
        $folder_data->name = $resource_name;            
        $folder_data->intro = '<p>'.$resource_name.'</p>';
        $folder_data->introformat = 1;
        $folder_data->revision = 1;
        $folder_data->timemodified = time();
        $folder_data->display = 0;
        $folder_data->showexpanded = 1;
        $folder_data->showdownloadfolder = 1;

        $folder_id = $DB->insert_record('folder', $folder_data);

        echo "folder id: " . $folder_id;

        // add course module
        $cm = new stdClass();
        $cm->course = $courseid;
        $cm->module = $module->id; // should be retrieved from mdl_modules
        $cm->instance = $folder_id; // from mdl_resource
        $cm->section = $sectionid->id; // from mdl_course_sections
        $cm->visible = 1;
        $cm->visibleold = 1;
        $cm->showavailability = 1;
        $cm->added = time();

        $cmid = $DB->insert_record('course_modules', $cm);

        // add module to course section so it'll be visible
        if ($DB->record_exists('course_sections', array('course' => $courseid, 'section' => 1))) {
            $sectionid = $DB->get_record('course_sections', array('course' => $courseid, 'section' => 1));

            // if sequence is not empty, add another course_module id
            if (!empty($sectionid->sequence)) {
                $sequence = $sectionid->sequence . ',' . $cmid;
            } else {
                // if sequence is empty, add course_module id
                $sequence = $cmid;
            }

            $course_section = new stdClass();
            $course_section->id = $sectionid->id;
            $course_section->course = $courseid;
            $course_section->section = 1;
            $course_section->sequence = $sequence;
            $csid = $DB->update_record('course_sections', $course_section);

        } else {

            $sequence = $cmid;

            $course_section = new stdClass();
            $course_section->course = $courseid;
            $course_section->section = 1;
            $course_section->sequence = $sequence;

            $csid = $DB->insert_record('course_sections', $course_section);
        }

        rebuild_course_cache($courseid, true);      

        // get context again, this time with all resources present
        $context = get_folder($courseid, $resource_name);
        return $context;

    } else {
        $context = context_module::instance($coursemodule->cmid); 

        return $context;
    }
} // get_folder

