Quellcode durchsuchen

Update 'files_functions.php'

Synchronizing iAssign Git with the current iAssign stable version (until Moodle 5.0).
Small changes in: ilm_manager.php, lang/*/iassign.php
Bigger changes in: ilm_manager_form.php, lib.php, settings_form.php, settings.php, version.php, backup/moodle2/*.php, ilm_debug/escreva.php, ilm_handlers/java.php
New iLM versions: iassign/ilm/iFractions/, iassign/ilm/iHanoi/, iassign/ilm/iVProg/
New file (was missing): settings_activities.php
leo vor 2 Wochen
Ursprung
Commit
7fb5751769
1 geänderte Dateien mit 300 neuen und 77 gelöschten Zeilen
  1. 300 77
      files_functions.php

+ 300 - 77
files_functions.php

@@ -1,7 +1,6 @@
 <?php
 
 /*
-
  * Any Moodle activity is directly associated of a Moodle instance activity through {course_modules}.
  * 
  * iAssign is no directly associated of a Moodle instance activity, since it is a block of activities,
@@ -15,7 +14,7 @@
  * {context} : id ; contextlevel ; instanceid ; path ; depth ; locked
  * {course_modules} : id ; course ; module ; instance ...
  * + {course_modules}.course   = {course}.id
- * + {course_modules}.module   = {module}.id
+ * + {course_modules}.module   = {module}.id    - is the module id (example, if iAssign has {module}.id=7 => {course_modules}.module = 7
  * + {course_modules}.instance = {iassign}.id   - associate with activities block
  * 
  */
@@ -155,8 +154,6 @@ function get_all_iassign_statement ($DB) {
   print "Total: " . $total . "<br/> Vector: "; print_vector($vec_all_names_ord); print "<br/>";
   } // function get_all_iassign_statement($DB)
 
-// Patricia Alves (admin)      => user.id = 24 ; patriciaadm ; profa.dra.patricia@gmail.com
-// Patricia Alves (professora) => user.id = 1332 ; patricia ; profa.pati@gmail.com
 
 // Get all iAssign {files}
 // Build "$list_all_files" with fields:  id contenthash contextid component filearea itemid filepath filename userid author timecreated ias_id
@@ -168,19 +165,14 @@ function get_all_files ($DB, $list_iassign) {
   $sizeAC = count($list_iassign);
   //L echo "----<br/>get_all_files: #list_iassign=" . $sizeAC . "<br/>\n";
 
-//'component' => 'mod_iassign', 'filearea' => 'exercise', 'contextid' => 108:
-//get_all_files: #list_iassign=772
-//#tmp_list_all_files=12
+  // Usual access to {files} is through:
+  //  $fs = get_file_storage();
+  //  $files = $fs->get_area_files($context_id, 'mod_iassign', 'exercise', $iassign_statement_id); 
+  // using: ./lib/filestorage/file_storage.php: public function get_area_files($contextid, $component, $filearea, $itemid = false,...)
 
-//get_all_files: #list_iassign=772
-//#tmp_list_all_files=7382
-  //$tmp_list_all_files = $DB->get_records('files', array('component' => 'mod_iassign', 'filearea' => 'exercise')); // #tmp_list_all_files=8324
-  //$tmp_list_all_files = $DB->get_records('files', array('component' => 'mod_iassign')); // #tmp_list_all_files=7382 could be 'filearea' => 'activity'
-  //$tmp_list_all_files = $DB->get_records('files', array('component' => 'mod_iassign', 'filearea' => 'activity')); // #tmp_list_all_files=4991
-  //$tmp_list_all_files = $DB->get_records('files', array('component' => 'mod_iassign')); // #tmp_list_all_files=8324 // , 'filearea' => 'exercise', 'contextid' => 108
   $str_query = "SELECT * FROM {files} WHERE component='mod_iassign'"; // "; // AND filearea='exercise' AND contextid=108
   $tmp_list_all_files = $DB->get_records_sql($str_query); // get array of stdClass (must be only one element)
-  //print_r($tmp_list_all_files); echo "<br/>"; // Array ( [37] => stdClass Object ( [id] => 3...
+  //D print_r($tmp_list_all_files); echo "<br/>"; // Array ( [37] => stdClass Object ( [id] => 3...
 
   $numf = count($tmp_list_all_files);
   //L echo "#tmp_list_all_files=" . $numf . "<br/>"; // #tmp_list_all_files=13383
@@ -256,6 +248,35 @@ function search_files (&$list_all_files, $element_ias) {
   } // function search_files($list_all_files, $element_ias)
 
 
+// Get all {files} in one specific {course}.id
+// Get all of its context, then all of their {files}
+// @calledby locallib.php ! view_files_ilm($iassign_ilm_class, $extension)
+function get_all_files_course ($DB, $courseid, $fs) {
+  $modules_iassing_id = get_iassign_id($DB); // get 'id, name, visible' from 'modules' with upper(name)='IASSIGN'
+
+  //ATTENTION: since 'get_records_sql(.)' will return only the first element (first field), it is necessary to use as first column {context}.id
+  // {course_modules}.instance = {context}.instanceid = {iassign}.id
+  $str_query = "SELECT {context}.id AS contextid, {course_modules}.id, {course_modules}.instance, {context}.instanceid FROM {course_modules},{context} ".
+    " WHERE {course_modules}.id = {context}.instanceid AND {course_modules}.course = " . $courseid . " AND {course_modules}.module = " . $modules_iassing_id;
+  //TODO? $array_timecreated = array(); //TODO order by {files}.timecreated?
+  $array_all_files = array();
+  //D echo "files_functions.php ! get_all_files_course(.)<br/>\n";
+  //ATTENTION: 'get_records_sql(.)' return only the first element (first field)
+  $array_course_modules_context = $DB->get_records_sql($str_query);
+  foreach ($array_course_modules_context as $item_cm) {
+    $files_tree = $fs->get_area_files($item_cm->contextid, 'mod_iassign', 'exercise');
+    foreach ($files_tree as $onefile)
+      if ($onefile->get_filename()!='.') {
+        $array_all_files[] = $onefile;
+        //TODO? $array_timecreated[] = $item; //TODO Use "asort($array_timecreated);" to order?
+        //D echo " - id=" . $onefile->get_id() . ", contextid=" . $onefile->get_contextid() . ", filename=" . $onefile->get_filename() . "<br/>\n";
+        }
+    }
+  //D echo "files_functions.php ! get_all_files_course(.): #array_all_files=" . count($array_all_files) . "<br/>\n";
+  return $array_all_files;
+  }
+
+
 // Get {iassign_statement} or {files}
 // @calledby settings_process_files_form.php
 function get_iassignstatement_or_files ($DB, $table, $element_id) {
@@ -268,39 +289,187 @@ function get_iassignstatement_or_files ($DB, $table, $element_id) {
   }
 
 
+// To be used in restoring backup
+// @calledby ./mod/iassign/backup/moodle2/restore_iassign_stepslib.php
+function get_all_files_ia ($DB, $ias_id, $ias_file, $ias_filesid, $ias_name) {
+  // Try to get all associated {files} using: {files}.itemid = {iassign_statement}.id
+  $files = $DB->get_records('files', array('component' => 'mod_iassign', 'filearea' => 'exercise', 'itemid' => $ias_id));
+  if ($files)
+    return $files;
+  // Now try with: {files}.itemid = {iassign_statement}.file
+  $files = $DB->get_records('files', array('component' => 'mod_iassign', 'filearea' => 'exercise', 'itemid' => $ias_file));
+  if ($files)
+    return $files;
+  // Now try with: {files}.itemid = {iassign_statement}.file
+  $files = $DB->get_records('files', array('component' => 'mod_iassign', 'filearea' => 'exercise', 'itemid' => $ias_filesid));
+  return $files;
+  }
+
+
+//TODO: remover funcao 'get_from_files(.)' do locallib.php (linha: 358)
+// Get the element associated to {iassign_statement} in {files}
+// Since the association was changed in 2020/12/05, but was upgrade non consistent,
+// this try to recover with: {files}.itemid = {iassign_statement}.id, after with {iassign_statement}.file and then with {iassign_statement}.filesid
+// @return array({files}, {files}) or NULL
+// @calledby locallib.php ! add_edit_iassign() ; duplicate_activity()
+// @calledby ilm_handlers/html5.php !show_activity_in_ilm(.)
+function get_from_files ($ia_id, $ia_file, $ia_filesid, $fs, $contextid, $component, $filearea) {
+  global $USER;
+  //D if ($USER->id==3) echo " USER->id==3: files_function.php: get_from_files(.) - {user}.id=3: component=" .$component . "<br/>\n"; //leo
+  $files_list = false;
+  if ($ia_id) // try association: {files}.itemid = {iassign_statement}.id
+    $files_list = $fs->get_area_files($contextid, $component, $filearea, $ia_id);
+  //D if ($USER->id==3) echo " USER->id==3: + get_area_files com ia_id=" . $ia_id . " => #files_list=" . count($files_list). "<br/>\n"; //leo remover!
+  if (!$files_list) { // not found with {files}.itemid = {iassign_statement}.id
+    if ($ia_file) // try association: {files}.itemid = {iassign_statement}.file
+      $files_list = $fs->get_area_files($contextid, $component, $filearea, $ia_file); // try with {iassign_statement}.file
+    //D if ($USER->id==3) echo " USER->id==3: + get_area_files com ia_file=" . $ia_file . "<br/>\n"; //leo remover!
+    if (!$files_list) { // not found with {files}.itemid = {iassign_statement}.file
+      if ($ia_filesid) // try association: {files}.itemid = {iassign_statement}.filesid
+        $files_list = $fs->get_area_files($contextid, $component, $filearea, $ia_filesid); // try with {iassign_statement}.filesid
+      //D if ($USER->id==3) echo " USER->id==3: + get_area_files com ia_filesid=" . $ia_filesid . "<br/>\n"; //leo remover!
+      if (!$files_list) return NULL; // error!
+      }
+    }
+  $f1_obj = NULL; // will receive the element of {files} with regular 'filename'
+  $f2_obj = NULL; // will receive the correspondent element of $f1_obj with directory, i.e, filename=='.'
+  foreach ($files_list as $one_files) { // when activity is duplicated => it has only the regular 'filename'
+    if ($one_files->get_filename()!=".") $f1_obj = $one_files; // $files_list[0]; // from {files}
+    else $f2_obj = $one_files; // $files_list[1]; // from {files}
+    } 
+  // if $f2_obj!=NULL but $f2_obj==NULL, then probably $f1_obj was recovered by 'files_functions.php!get_from_filesAll(.)' in the previous edition
+  //D if ($USER->id==3) echo " USER->id==3: * &nbsp; id=" . $f1_obj->get_id() . ", filename=" . $f1_obj->get_filename() . "<br/>\n"; //REMOVER
+  return array($f1_obj, $f2_obj);
+  } // function get_from_files($ia_id, $ia_file, $ia_filesid, $fs, $contextid, $component, $filearea)
+
+
+// Debug function: list all {files} considering only {context}.id and {files}.component='mod_iassign' and ({files}.filearea='exercise' or {files}.filearea='activity')
+// Using: ./lib/filestorage/file_storage.php: public function get_area_files($contextid, $component, $filearea, $itemid = false,...)
+ // @return array({files}, {files}) or NULL
+// @calledby locallib.php ! add_edit_iassign()
+function get_from_filesAll ($fs, $contextid, $component, $filearea) {
+  global $USER, $DB;
+  if ($USER->id==3) echo "-------<br/>USER->id==3: files_function.php: get_from_filesAll(.) - {user}.id=3 : contextid=" . $contextid . ", component=" . $component . ", filearea=" . $filearea . "<br/>\n"; //leo
+  // SELECT id,contextid,component,filearea,itemid,filename,author FROM s_files WHERE contextid=51250 AND (filearea='exercise' OR filearea='activity')
+  $files_list = false;
+  //x $files_list = $fs->get_area_files($contextid, $component, $filearea, false, $sort = "itemid, filepath, filename"); // volta vazio!
+  $files_list = $DB->get_records('files', array('contextid' => $contextid, 'component' => 'mod_iassign', 'filearea' => $filearea)); //
+  if ($USER->id==3) {
+    echo " USER->id==3: + #files_list=" . count($files_list) . "<br/>\n"; //leo remover!
+    }
+  if (!$files_list) return NULL; // error!
+  return $files_list;
+  } // function get_from_filesAll($fs, $contextid, $component, $filearea)
+
+
+
+// Update {files}.itemid to {iassign_statement}.id
+// Came here when teacher send the form to update one activity and {files} already exists!
+// @calledby locallib.php: update_iassign($param): 
+function update_files ($DB, $one_file_id, $ia_id) {
+  $newf = new stdClass();
+  $newf->id = $one_file_id;
+  $newf->itemid = $ia_id;
+//D echo "files_functions.php: update_files(.): {files}.id=" . $one_file_id . ", {iassign_statement}.id=" . $ia_id . ": {files}.itemid <- " . $ia_id . "<br/>";
+//D exit; //REMOVER exit
+  if (!$DB->update_record('files', $newf)) return FALSE; // not error    
+  return TRUE;
+  }
+
+
 // Update {iassign_statement}.filesid and {files}.itemid
-// @calledby settings_process_files_form.php
-function update_iassignstatement_files ($DB, $ia_id, $filesid, $is_obj, $f1_obj, $f2_obj) {
-  //D echo "files_functions.php|update_iassignstatement_files: ia_id=" . $ia_id . ", files.id=" . $filesid . "<br/>\n";
-  //$ia_obj = $DB->get_record($table, array('id' => $element_id));
-  $ma  = "{iassign_statement}.filesid=" . $is_obj->filesid;
-  $mf1 = "{files}: id=" . $f1_obj->id . ": itemid=" . $f1_obj->itemid;
-  $mf2 = "{files}: id=" . $f2_obj->id . ": itemid=" . $f2_obj->itemid;
-  $is_obj->filesid = $filesid; // {iassign_statement}.filesid := $f1_obj->ud = {files}.id
-  $f1_obj->itemid = $ia_id;
-  $f2_obj->itemid = $ia_id;
-  $ma  .= " -> " . $is_obj->filesid;
-  $mf1 .= " -> " . $f1_obj->itemid;
-  $mf2 .= " -> " . $f2_obj->itemid;
+// Temporary function to restore relation {iassign_statement}/{files}
+// First version of iAssign used a random value to associate 'files.itemid' with 'iassign_statement.file'
+// Came here when teacher try to edit any activity, during the form preparation
+// @param $DB = database
+// @param $ia_id = {iassign_statement}->id
+// @param $filesid = {iassign_statement} object
+// @param $is_obj = {iassign_statement} object
+// @param $f1_obj = {files} obj with id=$filesid ($filesid an specific {files}->id)
+// @param $f2_obj = {files} obj with id=$filesid+1
+// @calledby settings_process_files_form.php: $answer = update_iassignstatement_files($DB, $iassign_statement_id, $filesid, $is_obj, $f1_obj, $f2_obj);
+// @calledby locallib.php:add_edit_iassign(): $result = update_iassignstatement_files($DB, $is_obj->id, $f1_obj->get_id(), $is_obj, $f1_obj, $f2_obj);
+function update_iassignstatement_files ($DB, $ia_id, $filesid, $is_obj, $f1_obj, $f2_obj = NULL, $context = NULL) {
+  global $USER;
+  // Came here with something like: $ia_obj = $DB->get_record($table, array('id' => $element_id));
+  $ma  = "{iassign_statement}: id=" . $ia_id . " : filesid=" . $is_obj->filesid; //D
+  $mf1 = "{files}: id=" . $f1_obj->get_id() . ": itemid=" . $f1_obj->get_itemid(); //D
+  $mf2 = "{files}: [empty]"; //D
+
+  $is_obj_filesid = $is_obj->filesid; // {iassign_statement}.filesid initial
+  $is_obj->filesid = $filesid; // {iassign_statement}.filesid := $f1_obj->id = {files}.id
+  $is_obj->file = $filesid;    // {iassign_statement}.file    := $f1_obj->id = {files}.id (update also the old field 'file')
+
+  $f1_obj->id = $f1_obj->get_id();
+  $f1_obj_itemid = $f1_obj->get_itemid(); // first {files}.itemid initial
+  $f1_obj->itemid = $ia_id; // Necessary to force {files}.id, otherwise will occurs the error:
+
+  $ma  .= " -> " . $is_obj->filesid; //D
+  $mf1 .= " -> " . $f1_obj->itemid . " (id=" . $f1_obj->get_id() . ")"; //D
+
   $error = FALSE;
-  if (!$DB->update_record('iassign_statement', $is_obj)) $error = TRUE; // print_error('error_update', 'iassign');
-  if (!$DB->update_record('files', $f1_obj)) $error = TRUE;
-  if (!$DB->update_record('files', $f2_obj)) $error = TRUE;
+  // If {iassign_statement}.filesid != {files}.id update {iassign_statement}
+  if ($is_obj_filesid != $filesid) // update {iassign_statement} defining: {iassign_statement}.filesid = {files}.id
+    if (!$DB->update_record('iassign_statement', $is_obj)) $error = TRUE; // print_error('error_update', 'iassign');
+  // If {files}.itemid != {iassign_statement}.id != update {filesid} (for file with 'filename')
+  if ($f1_obj_itemid != $ia_id) // update first {files}.item with {iassign_statement}.id
+    if (!$DB->update_record('files', $f1_obj)) $error = TRUE;
+
+  if (is_null($f1_obj_itemid)) $f1_obj_itemid = -1; // to avoid error when {files} is not found
+  $f2_obj_itemid = -1; // to avoid error when {files} is not found
+  if ($f2_obj!=NULL) {
+    $mf2 = "{files}: id=" . $f2_obj->get_id() . ": itemid=" . $f2_obj->get_itemid(); //D
+    $mf2 .= " -> " . $f2_obj->get_itemid() . " (id=" . $f2_obj->get_id() . ")"; //D
+    $f2_obj->id = $f2_obj->get_id();
+    $f2_obj_itemid = $f2_obj->get_itemid(); // second {files}.itemid initial
+    $f2_obj->itemid = $ia_id; // moodle_database::update_record_raw() id field must be specified.
+    // If {files}.itemid != {iassign_statement}.id != update {filesid} (for file with directory, filename='.')
+    if ($f2_obj_itemid != $ia_id) // update second {files}.item with {iassign_statement}.id
+      if (!$DB->update_record('files', $f2_obj)) $error = TRUE;
+    }
+  //D echo "files_functions.php!update_iassignstatement_files(.): 4<br/>"; //exit;//leo
+
+  //DEBUG
+  if ($USER->id==3) { //D REMOVER
+    $troca = 0; // locallib.php!add_edit_iassign(): $context = context_module::instance($this->cm->id); 
+    echo "<br/><br/><br/><table><tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>";
+    echo "<td>USER->id==3: files_functions.php: update_iassignstatement_files(): USER==3</td></tr>\n";     
+    echo "<tr><td></td><td>\$COURSE context: id=" .$context->id . "</td></tr>\n";
+    echo "<tr><td></td><td>{iassign_statement}: id=" .$ia_id . ", file=" . $is_obj->file . ", filesid=" . $is_obj->filesid . "</td></tr>\n";
+    echo "<tr><td></td><td>{files} 1: id=" . $f1_obj->get_id() . ", contextid=" . $f1_obj->get_contextid() . ", itemid=" . $f1_obj->itemid . ", filearea=" . $f1_obj->get_filearea() .
+	 ", filepath=" . $f1_obj->get_filepath() . ", filename=" . $f1_obj->get_filename() . ", userid=" . $f1_obj->get_userid() . "</td></tr>\n";
+    echo "<tr><td></td><td>{files} 1 : " .$mf1 . "</td></tr>\n";
+    echo "<tr><td></td><td>{files} 2 : " .$mf2 . "</td></tr>\n";
+    if ($is_obj_filesid != $filesid) { echo "<tr><td></td><td>&nbsp; - tenta: update {iassign_statement}.filesid with {files}.id ******* deveria TROCAR!</td></tr>\n"; $troca = 1; }
+    else echo "<tr><td></td><td>&nbsp; - NAO troca iassign_statement</td></tr>\n";
+    if ($f1_obj_itemid != $ia_id) { echo "<tr><td></td><td>&nbsp; - tenta: f1: update first {files}.item with {iassign_statement}.id f1.itemid=" . $f1_obj_itemid . "<-" . $ia_id . " ******* deveria TROCAR!</td></tr>\n"; $troca = 1; }
+    else echo "<tr><td></td><td>&nbsp; - NAO troca files f1</td></tr>\n";
+    if ($f2_obj_itemid != $ia_id) { echo "<tr><td></td><td>&nbsp; - tenta: f2: update second {files}.item with {iassign_statement}.id: f2.itemid=" . $f2_obj_itemid . "<-" . $ia_id . " ******* deveria TROCAR!</td></tr>\n"; $troca = 1; }
+    else echo "<tr><td></td><td>&nbsp; - NAO troca files f1</td></tr>\n";
+    echo "<tr><td></td><td>&nbsp; * " . $ma . " / " . $mf1 . " / " . $mf2 . "</td></tr>\n\n";
+    if ($troca == 1) {
+      if (!$error) echo "<tr><td></td><td>&nbsp; - atualizou {iassign_statement} e {files} com sucesso!</td></tr>\n<tr><td></td><td>Depuracao: USER->id==3</td></tr>\n";
+      else echo "<tr><td></td><td>&nbsp; - ERRO! NAO atualizou {iassign_statement} e {files}!</td></tr>\nDepuracao: USER->id==3</td></tr>\n";
+      // exit; //REMOVER exit
+      }
+    }
   if (!$error) {
-    echo " * " . $ma . " / " . $mf1 . " / " . $mf2 . "<br/>\n";
+    if ($USER->id==3) echo "<tr><td></td><td>USER->id==3: &nbsp; * " . $ma . " / " . $mf1 . " / " . $mf2 . "</td></tr></table>\n\n"; //D
     return TRUE;
     }
-  echo " x " . $ma . " / " . $mf1 . " / " . $mf2 . " --- ERROR!<br/>\n";
-  return FALSE;
-  //$files = $DB->get_records('files', array('contextid' => $contextid, 'component' => 'mod_iassign', 'filearea' => 'exercise', 'itemid' => $iassign_statement->id)); //
+  if ($USER->id==3) echo "<tr><td></td><td>USER->id==3: &nbsp;  x " . $ma . " / " . $mf1 . " / " . $mf2 . " --- ERROR!</td></tr></table>\n\n"; //D
+    return FALSE;
   } // function update_iassignstatement_files($DB, $ia_id, $filesid, $is_obj, $f1_obj, $f2_obj)
 
 
 // List all "$list_all_files[$jj]" with field "ias_id" == -1 (candidate to be the missing file)
-// Prepare HTML do "settings_process_files_form.php" then send to this->update_iassign_statement_files(.) function to update {iassign_statement} and {files}
+// Prepare HTML to "settings_process_files_form.php" then send to this->update_iassign_statement_files(.) function to update {iassign_statement} and {files}
+// The "settings_verify.php" calls "see_all_iass_files(.)" and "list_all_iass_files(.)"
 // @param $type = 1 => do not edit "$list_all_files[$jj].ias_id" (leave with -1); 2 => edit "$list_all_files[$jj].ias_id" with its first fit {iassign_statement}.ias_id
 // @param &$list_all_files: passed by reference, "$list_all_files[$jj].ias_id" could receive {iassign_statement}.id if {files}.contextid = some {context}.id of {iassign_statement}; files[$jj].courseid" := $courseid,
 // @param $contextid : is array of context in this {iassign_statement}; $ias_id = {iassign_statement}.id
+// @calledby this->list_all_iass_files($DB, $modules_iassignid): [$msgCandidates, $msgHidden, $files_index_candidates, $contextid_candidates, $list_candidate_filesbyID] = search_lost_files_in_context(2,...)
+// @calledby this->see_all_iass_files($DB, $modules_iassignid): [$msgCandidates, $msgHidden, $files_index_candidates, $contextid_candidates, $list_candidate_filesbyID] = search_lost_files_in_context(1, ...)
 function search_lost_files_in_context ($type, $ii, $courseid, $ias_id, &$list_all_files, $array_contextid, $countErr) {   
   $sizeOfFiles = count($list_all_files);
   $sizeC = count($array_contextid);
@@ -831,14 +1000,33 @@ function get_associated_files ($DB, $iassign_statement, $all_context, &$all_cont
 
 
 // @calledby locallib.php : add_edit_iassign(.)
-// @calledby settings_activities.php: [$list_all_instances_of_iassign, $all_context, $list_of_ia_files] = get_files($courseid, $DB); // inside 'files_functions.php'
-function get_files ($course_id, $DB) { //2022
+// @calledby settings_activities.php: [$list_all_instances_of_iassign, $all_context, $list_of_ia_files...] = get_files($courseid, $ilm_id, $DB);
+function get_files ($course_id, $ilm_id, $DB) { //2022
   //__ echo "get_files(.): course_id=" . $course_id . "<br/>";
   // Get all iAssignment block inside this course
-  if (isset($course_id) && $course_id)
-    $answer_list_iassign = $DB->get_records('iassign', array('course' => $course_id)); //R $this->get_courseid() -> $course_id
+  if (isset($ilm_id) && $ilm_id) {
+    $str_query = "SELECT DISTINCT {iassign}.* FROM {iassign}, {iassign_statement} WHERE " .
+      " {iassign}.id={iassign_statement}.iassignid AND {iassign_statement}.iassign_ilmid=" . $ilm_id;
+    //D echo "str_query=" . $str_query . "<br/>"; // SELECT {context}.id AS contextid, {course}.id, {course}.fullname, {course}.shortname, {course_modules}.id AS course_module_id, {context}.instanceid FROM {course}, {context}, {course_modules} WHERE {course}.id={course_modules}.course AND {course_modules}.id={context}.instanceid AND {course_modules}.instance=?
+    $aux_answer_list_iassign = $DB->get_records_sql($str_query); // get array of stdClass (must be only one element)
+    //D echo "#aux_answer_list_iassign=" . count($aux_answer_list_iassign) . "<br/>";
+    $answer_list_iassign = array(); // transform the associative array in one that is continous
+    foreach ($aux_answer_list_iassign as $item) {
+      $answer_list_iassign[] = $item;
+      }
+    //D echo "#answer_list_iassign=" . count($answer_list_iassign) . "<br/>";
+    //D $sizeIA = count($answer_list_iassign);
+    //D for ($ii=0; $ii<$sizeIA; $ii++) echo $ii . " : " . $answer_list_iassign[$ii]->id . ", " . $answer_list_iassign[$ii]->name . ", " . $answer_list_iassign[$ii]->author_name . "<br/>\n";
+    //D exit;
+    }
   else
-    $answer_list_iassign = $DB->get_records('iassign'); // all courses
+  if (isset($course_id) && $course_id) // not yet used...
+    $answer_list_iassign = $DB->get_records('iassign', array('course' => $course_id)); //R $this->get_courseid() -> $course_id
+  else {
+    print "Attention, parameters {course}.id and {modules}.id of iAssign not defined!<br/>";
+    exit(1);
+    // $answer_list_iassign = $DB->get_records('iassign'); // all courses
+    }
    //$tmp_list_ias = $DB->get_records_sql($str_query); // get array of stdClass (must be only one element)
 //D echo "#answer_list_iassign = " . sizeof($answer_list_iassign) . "<br/>";
 //$list_iassign = $DB->get_records('iassign');
@@ -848,13 +1036,17 @@ function get_files ($course_id, $DB) { //2022
   // Build 3 arrays (list_all_instances_of_iassign[.], all_context[.], list_of_files[.])
   // - $list_all_instances_of_iassign[$ii] <-> $all_context[$ii] <-> $list_of_files[$ii]
 
+  // Build all context per course
+  $list_of_contextid_by_courses = array(); // list of courses by ID ({course}.id): $list_of_contextid_by_courses[$i] = array(with all of its context)
+  $list_of_courses = array(); // list of {course}.id: $list_of_courses[$i] = array(with {course}.id, {course}.fullname, {course}.shortname)
+  $list_of_coursesid = array(); // auxiliary to easy to generate $list_of_courses[]
+
   // Get all context of each iAssignment block inside this course: $list_all_instances_of_iassign[.] ; $all_context[.]
   $list_all_instances_of_iassign = array(); // will return { id, contextid, shortname} = { iassign.id, context.id, course.shortname } <-> $list_of_files[.]
   $all_context_final = array(); // will be defined by $all_context considering eventually more then one context to recover {files}
   $all_context = array();
   $ii = 0;
   foreach ($answer_list_iassign as $iassign) { // get all context of each iAssign block: this iAssign block $iassign
-    $list_all_instances_of_iassign[] = $iassign;
     //DEBUG: the abstract function of "/lib/dml/moodle_database.php!get_records_sql(.)" are returning only half of rows! Than is recommended to use 'get_in_or_equal(.)'!
     //DEBUG: ATTENTION, get_records_XX() family of functions inside Moodle always returns one associative array, i.e. one array of records where the key is the first field in the SELECT clause.
     //DEBUG: So, if you get two records with the same value in the 1st field the functions will "group" them, returning the last one in the real recordset.
@@ -862,22 +1054,42 @@ function get_files ($course_id, $DB) { //2022
     //DEBUG: so we must use '{context}.id' since several of them could be associated to one {course_modules}
     $str_query = "SELECT {context}.id AS contextid, {course}.id, {course}.fullname, {course}.shortname, {course_modules}.id AS course_module_id, {context}.instanceid " .
       " FROM {course}, {context}, {course_modules} WHERE " .
-      " {course}.id={course_modules}.course AND {course_modules}.id={context}.instanceid AND {course_modules}.instance=" . $iassign->id;
+      " {course}.id={course_modules}.course AND {course_modules}.id={context}.instanceid AND {course_modules}.instance=" . $iassign->id . " AND {course}.id=" . $iassign->course .
+      " ORDER BY {course}.id, {course_modules}.instance"; // Redundance: {course_modules}.instance=" . $iassign->id . " AND {course}.id=" . $iassign->course
     //  " {course}.id={course_modules}.course AND {course_modules}.id={context}.instanceid AND {course_modules}.course=" . $course_id . " AND {course_modules}.instance=" . $iassign->id;
     //D echo "str_query=" . $str_query . "<br/>"; // SELECT {context}.id AS contextid, {course}.id, {course}.fullname, {course}.shortname, {course_modules}.id AS course_module_id, {context}.instanceid FROM {course}, {context}, {course_modules} WHERE {course}.id={course_modules}.course AND {course_modules}.id={context}.instanceid AND {course_modules}.instance=?
     $answer_list = $DB->get_records_sql($str_query); // get array of stdClass (must be only one element)
 
     //D if ($iassign->id==1299) { // ($iassign->id==1) { //
     //D  echo "query=" . $str_query . "<br/>#answer_list=" . count($answer_list) . ": <br/>"; } // print_r($answer_list); echo "<br/>"; }
+
     $list1 = array();
     $strAux = "";
-    foreach ($answer_list as $item) {
-      $list1[] = $item;
+    foreach ($answer_list as $item) { // $answer_list[] from {context}, {course} and {course_modules}
+      $list1[] = $item; // transform the associative array in one that is continous
+      $courseid = $item->id;
+      if (!in_array($courseid, $list_of_coursesid)) { // array of contextid not initiated for this course
+        $list_of_courses[] = array($item->id, $item->shortname, $item->fullname); // list of courses array({course}.id, {course}.shortname, {course}.fullname)
+        $list_of_coursesid[] = $item->id; // auxiliary to easy to generate $list_of_courses[]
+        $iassign->courseid = $item->id;
+        $iassign->fullname = $item->fullname;
+        //DD echo "(".$item->id.",".$item->shortname .") ";
+        }
+      if (!isset($list_of_contextid_by_courses[$courseid])) { // array of contextid not initiated for this course
+        $list_of_contextid_by_courses[$courseid] = array($item->contextid); // list of courses by ID ({course}.id)
+        }
+      else // already initiated this course
+        array_push($list_of_contextid_by_courses[$courseid], $item->contextid); // append a new contextid
+
       //_ $strAux = "[" . $item->id . "," . $item->contextid . "," . $item->course_module_id . "," . $item->shortname . "," . $item->instanceid . "] ";
       //_ if ($iassign->id==1299) { // ($iassign->id==1) { // print_r($item);
       //_   echo " - iassign.id=" . $list_all_instances_of_iassign[$ii]->id . ": [id,context.id,course_module.id,shortname,instanceid]=" . $strAux . "<br/>\n";
       //_   }
-      }
+      } // foreach ($answer_list as $item)
+    //DD echo "<br/>";
+
+    $list_all_instances_of_iassign[] = $iassign;
+
     $all_context[$ii] = $list1; // $list1[0]; // { course.id, course.fullname, course.shortname, context.id }
     //__ echo " - iassign.id=" . $list_all_instances_of_iassign[$ii]->id . ", contextid=" . $all_context[$ii]->contextid . ",  : " . $strAux . "<br/>\n"; //print_r($answer_list); echo "<br/>\n";
     $ii++;
@@ -892,7 +1104,10 @@ function get_files ($course_id, $DB) { //2022
   $sizeofList = $ii; // size of $all_context[]
   for ($ii=0; $ii<$sizeofList; $ii++) { // get all iAssign block of activities (course.moudules)
     $iassign = $list_all_instances_of_iassign[$ii];
-    $list_all_iassign_statement = $DB->get_records('iassign_statement', array('iassignid' => $iassign->id)); // get all activities inside this block
+    
+    // Get all activities inside this block, only to the iLM selected $ilm_id == {modules}.id
+    $list_all_iassign_statement = $DB->get_records('iassign_statement', array('iassignid' => $iassign->id, 'iassign_ilmid' => $ilm_id));
+      
     $list_of_files = array(); // $list_of_files[$ii] = { ia_id, ia_file, ia_filesid, filesid=files.id, filename=files.filename, itemid=files.itemid, contextid=files.contextid }
     //D__ echo  "#list_all_iassign_statement = " . count($list_all_iassign_statement) . " de iassign.id=" . $iassign->id . "<br/>\n"; //D2022
     foreach ($list_all_iassign_statement as $iassign_statement) { // get all iAssign activity inside the block '$list_all_iassign_statement'
@@ -951,22 +1166,22 @@ function get_files ($course_id, $DB) { //2022
       } // foreach ($list_all_iassign_statement as $iassign_statement)
     } // for ($ii=0; $ii<$sizeofList; $ii++)
 
-  return [$list_all_instances_of_iassign, $all_context_final, $list_of_ia_files];
+  return [$list_all_instances_of_iassign, $all_context_final, $list_of_ia_files, $list_of_contextid_by_courses, $list_of_courses];
   } // function get_files($course_id, $DB)
 
 
 // Codigo de teste tinha inserido em 'locallib.php' (era invocado linha 2458/9172): static function test_iassign_statement_files()
 // @calledby locallib.php : add_edit_iassign(.)
 function see_all_files_context ($course_id, $DB) { //2022 testar 'restore_iassign_stepslib.php()' - remover!
-// See mod/iassign/backup/moodle2/restore_iassign_stepslib.php : after_execute()
-// /var/www/html/moo391p/mod/iassign/backup/moodle2/restore_iassign_stepslib.php
+  // See mod/iassign/backup/moodle2/restore_iassign_stepslib.php : after_execute()
+  // /var/www/html/moo391p/mod/iassign/backup/moodle2/restore_iassign_stepslib.php
   //global $CFG, $DB, $USER;
   //$fs = get_file_storage();
 
-$context_id = 1;
-// $context = context_module::instance($USER->cm); //2022/02: get 'context.id' = 'files.contextid'
-echo "files_functions.php: context.id=" . $context_id . "<br/>\n";
-$countF = 0;
+  $context_id = 1;
+  // $context = context_module::instance($USER->cm); //2022/02: get 'context.id' = 'files.contextid'
+  echo "files_functions.php: context.id=" . $context_id . "<br/>\n"; //D
+  $countF = 0;
 
   // Get all iLM installed in iAssign
   $list_all_iassign_ilm = $DB->get_records('iassign_ilm', array('parent' => 0, 'enable' => 1));
@@ -981,8 +1196,9 @@ $countF = 0;
   foreach ($answer_list_iassign as $iassign) { // get all context of this iAssign block $iassign
     $list_all_instances_of_iassign[] = $iassign;
     $str_query = "SELECT {course}.id, {course}.shortname, {context}.id AS contextid FROM {course}, {context}, {course_modules} WHERE " .
-               "{course}.id={course_modules}.course AND {course_modules}.id={context}.instanceid AND {course_modules}.course=" . $course_id . " AND {course_modules}.instance=" . $iassign->id;
-//echo "query=" . $str_query . "<br/>";
+                 "{course}.id={course_modules}.course AND {course_modules}.id={context}.instanceid AND {course_modules}.course=" . $course_id .
+                 " AND {course_modules}.instance=" . $iassign->id;
+    //echo "query=" . $str_query . "<br/>";
     $answer_list = $DB->get_records_sql($str_query); // get array of stdClass (must be only one element)
     $list1 = array();
     $strAux = "";
@@ -996,10 +1212,10 @@ $countF = 0;
     $iassign = $list_all_instances_of_iassign[$ii];
     $list_all_iassign_statement = $DB->get_records('iassign_statement', array('iassignid' => $iassign->id)); // get all activities inside this block
     $contextid = $all_context[$ii]->contextid; // context of this 'iassign.id'
-//D echo  "#list_all_iassign_statement = " . count($list_all_iassign_statement) . " de iassign.id=" . $iassign->id . "<br/>\n"; //D2022
+    //D echo  "#list_all_iassign_statement = " . count($list_all_iassign_statement) . " de iassign.id=" . $iassign->id . "<br/>\n"; //D2022
     foreach ($list_all_iassign_statement as $iassign_statement) { // get all iAssign activity inside the block '$list_all_iassign_statement'
-//D echo  " - iassign_statement {id = " . $iassign_statement->id . ", file = " . $iassign_statement->file . ", filesid = " . $iassign_statement->filesid .
-//D "}; contextid=" . $contextid . ", date(timecreated)=" . date("Y/m/d H:i:s", $iassign_statement->timecreated) . " : " . $iassign_statement->name . "<br/>\n"; //D2022
+      //D echo  " - iassign_statement {id = " . $iassign_statement->id . ", file = " . $iassign_statement->file . ", filesid = " . $iassign_statement->filesid .
+      //D "}; contextid=" . $contextid . ", date(timecreated)=" . date("Y/m/d H:i:s", $iassign_statement->timecreated) . " : " . $iassign_statement->name . "<br/>\n"; //D2022
       // To avoid programming mistake on old version try to get 'files' with 'iassign_statement.id', 'iassign_statement.file' and 'iassign_statement.filesid'
       $files = $DB->get_records('files', array('contextid' => $contextid, 'component' => 'mod_iassign', 'filearea' => 'exercise', 'itemid' => $iassign_statement->id)); // all 'files' associated
       $numf = count($files); $countF += $numf; $msgO = "iassign_statement.id"; //D
@@ -1023,19 +1239,22 @@ $countF = 0;
       if ($numf > 0) { echo  " &nbsp; * files: " . $numf . ": " . $msgO . "<br/>\n"; //D
         $filename = array();
         foreach ($files as $element_file) { // analyse each '$element_file' of 'files'
-echo  " &nbsp; * files: id = " . $element_file->id . ", contextid = " . $element_file->contextid . ", itemid=" . $element_file->itemid . " : " . $element_file->filename . "<br/>\n"; //D
+          echo  " &nbsp; * files: id = " . $element_file->id . ", contextid = " . $element_file->contextid .
+                ", itemid=" . $element_file->itemid . " : " . $element_file->filename . "<br/>\n"; //D
           if ($element_file->filename != '.') { // get the '$element_file' that is not only "path"
             $filename = explode(".", $element_file->filename);
             if ($iassign_statement->filesid != $element_file->id) { // need to update 'iassign_statement.filesid'?
-              echo " &nbsp; &nbsp; &nbsp; &nbsp; Update 'iassign_statement.filesid'=" . $iassign_statement->filesid . " <- " . $element_file->id . " : " . $element_file->filename . "<br/>"; //2022
+              echo " &nbsp; &nbsp; &nbsp; &nbsp; Update 'iassign_statement.filesid'=" . $iassign_statement->filesid .
+                   " <- " . $element_file->id . " : " . $element_file->filename . "<br/>"; //2022
               $iassign_statement->filesid = $element_file->id; // 'iassign_statement.filesid' <- 'files.id' (update bellow) //2022
               }
             }
           if ($element_file->itemid != $iassign_statement->id) { // need to update 'files.itemid'? ('files.itemid <- iassign_statement.id') //2022
-//++ Deixar para outro corrigir! A partir de 'settings_activities.php'
+            //++ Deixar para outro corrigir! A partir de 'settings_activities.php'
             $newentry_be_updated = new stdClass(); $newentry_be_updated->id = $element_file->id; $newentry_be_updated->itemid = $iassign_statement->id;
-            echo " &nbsp; &nbsp; &nbsp; &nbsp; Update 'files.itemid': id=" . $newentry_be_updated->id . ", itemid=" . $element_file->itemid . "<-" . $newentry_be_updated->itemid . " : " . $element_file->filename . "<br/>"; //2022
-//R              if (!$DB->update_record('files', $newentry_be_updated)) print_error('error_update', 'iassign');
+            echo " &nbsp; &nbsp; &nbsp; &nbsp; Update 'files.itemid': id=" . $newentry_be_updated->id . ", itemid=" .
+                 $element_file->itemid . "<-" . $newentry_be_updated->itemid . " : " . $element_file->filename . "<br/>"; //2022
+            //R if (!$DB->update_record('files', $newentry_be_updated)) print_error('error_update', 'iassign');
             }
           } // foreach ($files as $element_file)
         $extension = ""; // extension of the current '$element_file'
@@ -1047,22 +1266,26 @@ echo  " &nbsp; * files: id = " . $element_file->id . ", contextid = " . $element
             echo " &nbsp; &nbsp; &nbsp; &nbsp; Update 'iassign_statement.iassign_ilmid': " . $iassign_statement->iassign_ilmid . " <- " . $iassign_ilm->id . "<br/>\n"; 
             }
           }
-//R          $DB->update_record("iassign_statement", $iassign_statement); // update 'iassign_statement' (mainly 'iassign_statement.filesid')
+          //R $DB->update_record("iassign_statement", $iassign_statement); // update 'iassign_statement' (mainly 'iassign_statement.filesid')
         } // if ($numf > 0)
       } // foreach ($list_all_iassign_statement as $iassign_statement)
     } // for ($ii=0; $ii<$sizeofList; $ii++)
-$timeWrite = date('Y_m_d_H_i_s'); // Year_Month_Day_Hour_Minutes_Seconds
-$filenamewrite = "_output_restore_after_execute_" . $timeWrite . ".txt";
-
-echo "restore_iassign_stepslib: " . $filenamewrite . "<br/>\nUsando: " . __DIR__ . "/../../ilm_debug/escreva.php" . "<br/>\n"; //D . str_replace("\n","<br>\n", $msgD) . "<br/>\n"; // __DIR__
 
-// ./mod/iassign/ilm_debug/escreva.php: writeContent($filetype1, $pathbase, $outputFile, $msgToRegister)
-// ./mod/iassign/ilm_debug/saida_restore_after_execute.txt
-//D require_once(__DIR__ . "/../../ilm_debug/escreva.php"); //leo REMOVER! xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-
-//D Grvar em: ./mod/iassign/ilm_debug/output_restore_after_execute_2022_02_dd_hh_mm_ss.txt
-//D $resp = writeContent("", "", $filenamewrite, $msgD); // ($filetype1, $pathbase, $outputFile, $msgToRegister) //leo tire comentario para gravar
-
-echo "restore_iassign_stepslib: resp=" . $resp . ", #files=" . $countF . "<br/>\n";
+  try {
+    $timeWrite = date('Y_m_d_H_i_s'); // Year_Month_Day_Hour_Minutes_Seconds
+    $filenamewrite = "_output_restore_after_execute_" . $timeWrite . ".txt";
+
+    echo "files_function.php!function see_all_files_context(.): " . $filenamewrite . "<br/>\nUsando: " . __DIR__ .
+         "/../../ilm_debug/escreva.php" . "<br/>\n"; //D . str_replace("\n","<br>\n", $msgD) . "<br/>\n"; // __DIR__
+
+    // ./mod/iassign/ilm_debug/escreva.php: writeContent($filetype1, $pathbase, $outputFile, $msgToRegister)
+    // ./mod/iassign/ilm_debug/saida_restore_after_execute.txt
+    //D require_once(__DIR__ . "/../../ilm_debug/escreva.php"); //leo REMOVER!
+    //D Gravar em: ./mod/iassign/ilm_debug/output_restore_after_execute_2022_02_dd_hh_mm_ss.txt
+    //D $resp = writeContent("", "", $filenamewrite, $msgD); // ($filetype1, $pathbase, $outputFile, $msgToRegister) //leo tire comentario para gravar
+    echo " resp=" . $resp . ", #files=" . $countF . "<br/>\n";
+    } catch (Exception $e) {
+      print 'files_function.php!function see_all_files_context(.): catch exception: ' . $e->getMessage() . "<br/>\n";
+      }
 
-  } // function see_all_files_context($course_id, $DB)
+  } // function see_all_files_context($course_id, $DB)