Merge branch 'master' of github.com:chamilo/chamilo-lms

pull/5953/head
Angel Fernando Quiroz Campos 9 months ago
commit abac015729
No known key found for this signature in database
GPG Key ID: B284841AE3E562CD
  1. 2
      assets/locales/ar.json
  2. 2
      assets/locales/ast_ES.json
  3. 2
      assets/locales/bg.json
  4. 1
      assets/locales/bn_BD.json
  5. 1
      assets/locales/bo_CN.json
  6. 1
      assets/locales/bs_BA.json
  7. 2
      assets/locales/ca_ES.json
  8. 1
      assets/locales/cs_CZ.json
  9. 1
      assets/locales/da.json
  10. 2
      assets/locales/de.json
  11. 2
      assets/locales/el.json
  12. 2
      assets/locales/en.json
  13. 1
      assets/locales/eo.json
  14. 4
      assets/locales/es.json
  15. 2
      assets/locales/eu_ES.json
  16. 1
      assets/locales/fa_AF.json
  17. 2
      assets/locales/fa_IR.json
  18. 2
      assets/locales/fi_FI.json
  19. 1
      assets/locales/fo_FO.json
  20. 4
      assets/locales/fr_FR.json
  21. 2
      assets/locales/fur.json
  22. 2
      assets/locales/gl.json
  23. 2
      assets/locales/he_IL.json
  24. 1
      assets/locales/hi.json
  25. 1
      assets/locales/hr_HR.json
  26. 1
      assets/locales/hu_HU.json
  27. 1
      assets/locales/id_ID.json
  28. 2
      assets/locales/it.json
  29. 2
      assets/locales/ja.json
  30. 1
      assets/locales/ka_GE.json
  31. 1
      assets/locales/ko_KR.json
  32. 1
      assets/locales/lt_LT.json
  33. 2
      assets/locales/lv_LV.json
  34. 1
      assets/locales/mk_MK.json
  35. 1
      assets/locales/ms_MY.json
  36. 2
      assets/locales/nl.json
  37. 1
      assets/locales/nn_NO.json
  38. 2
      assets/locales/oc.json
  39. 2
      assets/locales/pl_PL.json
  40. 1
      assets/locales/ps.json
  41. 2
      assets/locales/pt_PT.json
  42. 2
      assets/locales/qu_PE.json
  43. 2
      assets/locales/ro_RO.json
  44. 1
      assets/locales/ru_RU.json
  45. 2
      assets/locales/sk_SK.json
  46. 2
      assets/locales/sl_SI.json
  47. 1
      assets/locales/so_SO.json
  48. 2
      assets/locales/sr_RS.json
  49. 2
      assets/locales/sv_SE.json
  50. 1
      assets/locales/sw_KE.json
  51. 1
      assets/locales/th.json
  52. 2
      assets/locales/tl_PH.json
  53. 1
      assets/locales/tr.json
  54. 1
      assets/locales/uk_UA.json
  55. 1
      assets/locales/vi_VN.json
  56. 1
      assets/locales/xh_ZA.json
  57. 1
      assets/locales/yo_NG.json
  58. 2
      assets/locales/zh_CN.json
  59. 1
      assets/locales/zh_TW.json
  60. BIN
      public/img/copy.png
  61. BIN
      public/img/icons/32/attendance_list.png
  62. BIN
      public/img/icons/32/scorms.png
  63. BIN
      public/img/icons/32/scorms_na.png
  64. BIN
      public/img/icons/32/security.png
  65. BIN
      public/img/icons/32/security_na.png
  66. BIN
      public/img/icons/32/tools.png
  67. BIN
      public/img/icons/32/tools_na.png
  68. BIN
      public/img/icons/32/user.png
  69. BIN
      public/img/icons/32/user_na.png
  70. BIN
      public/img/save_pack.png
  71. 2
      public/main/course_info/infocours.php
  72. 1318
      public/main/inc/lib/TrackingCourseLog.php
  73. 44
      public/main/inc/lib/exercise.lib.php
  74. 45
      public/main/inc/lib/export.lib.inc.php
  75. 14
      public/main/inc/lib/extra_field_value.lib.php
  76. 209
      public/main/inc/lib/sessionmanager.lib.php
  77. 1335
      public/main/inc/lib/tracking.lib.php
  78. 2
      public/main/inc/lib/usergroup.lib.php
  79. 2
      public/main/my_space/myStudents.php
  80. 85
      public/main/session/session_list.php
  81. 133
      public/main/tracking/courseLog.php
  82. 2
      public/main/tracking/course_log_resources.php
  83. 17
      src/CoreBundle/Migrations/Schema/V200/Version20230913162700.php
  84. 2
      src/CourseBundle/Repository/CQuizRepository.php
  85. 21
      translations/messages.en.po
  86. 21
      translations/messages.es.po
  87. 23
      translations/messages.fr.po
  88. 21
      translations/messages.pot

@ -18,7 +18,7 @@
"Surveys": "\u0627\u0644\u0627\u0633\u062a\u0628\u064a\u0627\u0646\u0627\u062a",
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"Course settings": "\u0627\u0639\u062f\u0627\u062f\u0627\u062a \u0627\u0644\u0645\u0642\u0631\u0631",
"Sign in": "\u062a\u0633\u062c\u064a\u0644 \u0627\u0644\u062f\u062e\u0648\u0644",
"My courses": "\u0645\u0642\u0631\u0631\u0627\u062a\u064a",
"Start recording": "\u0628\u062f\u0623 \u0627\u0644\u062a\u0633\u062c\u064a\u0644",

@ -14,7 +14,7 @@
"Survey": "Encuesta",
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"Course settings": "Configuraci\u00f3n de la lleici\u00f3n",
"My courses": "Los mios cursos",
"Attach": "Attach",
"Home": "P\u00e1xina d'entamu",

@ -18,7 +18,7 @@
"Surveys": "\u0410\u043d\u043a\u0435\u0442\u0438",
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"Course settings": "\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438",
"My courses": "\u041c\u043e\u0438\u0442\u0435 \u043a\u0443\u0440\u0441\u043e\u0432\u0435",
"Attach": "Attach",
"Home": "\u041d\u0430\u0447\u0430\u043b\u043e",

@ -1,7 +1,6 @@
{
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"Attach": "Attach",
"Is it editable by the invitees?": "Is it editable by the invitees?",
"Field is required": "Field is required",

@ -1,7 +1,6 @@
{
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"Attach": "Attach",
"Is it editable by the invitees?": "Is it editable by the invitees?",
"Field is required": "Field is required",

@ -1,7 +1,6 @@
{
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"Attach": "Attach",
"Is it editable by the invitees?": "Is it editable by the invitees?",
"Field is required": "Field is required",

@ -18,7 +18,7 @@
"Surveys": "Enquestes",
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"Course settings": "Configuraci\u00f3 del curs",
"Sign in": "Accedeix",
"My courses": "La meva llista de cursos",
"Attach": "Attach",

@ -6,7 +6,6 @@
"Member": "\u010clen",
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"My courses": "Moje kurzy",
"Attach": "Attach",
"Home": "Dom\u016f",

@ -12,7 +12,6 @@
"Survey": "Evaluering",
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"My courses": "Min kursusoversigt",
"Attach": "Attach",
"Home": "Hjem",

@ -18,7 +18,7 @@
"Surveys": "Umfragen",
"Tracking": "Tracking",
"Course maintenance": "Kurspflege",
"Course setting": "Course setting",
"Course settings": "Kurs-Einstellungen",
"Sign in": "Eintragen",
"My courses": "Meine Kurse",
"Start recording": "Aufnahme starten",

@ -18,7 +18,7 @@
"Surveys": "\u0391\u03c0\u03bf\u03b3\u03c1\u03b1\u03c6\u03ad\u03c2",
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"Course settings": "\u03a1\u03c5\u03b8\u03bc\u03af\u03c3\u03b5\u03b9\u03c2 \u03bc\u03b1\u03b8\u03ae\u03bc\u03b1\u03c4\u03bf\u03c2",
"Sign in": "\u03a3\u03c5\u03bd\u03b4\u03b5\u03b8\u03b5\u03af\u03c4\u03b5",
"My courses": "\u03a4\u03b1 \u03bc\u03b1\u03b8\u03ae\u03bc\u03b1\u03c4\u03ac \u03bc\u03bf\u03c5",
"Attach": "Attach",

@ -18,7 +18,7 @@
"Surveys": "Surveys",
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"Course settings": "Course settings",
"Sign in": "Sign in",
"My courses": "My courses",
"Start recording": "Start recording",

@ -11,7 +11,6 @@
"Member": "Uzanto",
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"My courses": "miajn kursojn",
"Attach": "Attach",
"Home": "Komenco",

@ -18,7 +18,7 @@
"Surveys": "Encuestas",
"Tracking": "Tracking",
"Course maintenance": "Mantenimiento del curso",
"Course setting": "Course setting",
"Course settings": "Configuraci\u00f3n del curso",
"Sign in": "Ingresar",
"My courses": "Mis cursos",
"Start recording": "Lanzar la grabaci\u00f3n",
@ -447,7 +447,7 @@
"Cancel": "Cancelar",
"Event": "Event",
"Are you sure you want to delete this event?": "Are you sure you want to delete this event?",
"Edit introduction": "Edit introduction",
"Edit introduction": "Editar la introduccion",
"Show all": "Mostrar todos",
"Hide all": "Ocultar todo",
"Sort": "Ordenar",

@ -18,7 +18,7 @@
"Surveys": "Inkestak",
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"Course settings": "Ikastaroaren ezarpenak",
"My courses": "Nire ikastaroak",
"Attach": "Attach",
"Home": "Hasierakoa",

@ -1,7 +1,6 @@
{
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"Attach": "Attach",
"Is it editable by the invitees?": "Is it editable by the invitees?",
"Field is required": "Field is required",

@ -18,7 +18,7 @@
"Surveys": "\u0628\u0631\u0631\u0633\u06cc",
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"Course settings": "\u062a\u0646\u0638\u06cc\u0645\u0627\u062a \u062f\u0631\u0633",
"My courses": "\u0641\u0647\u0631\u0633\u062a \u062f\u0631\u0648\u0633 \u0645\u0646",
"Attach": "Attach",
"Home": "\u0635\u0641\u062d\u0647 \u0627\u0635\u0644\u06cc",

@ -15,7 +15,7 @@
"Surveys": "Kyselyt",
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"Course settings": "Kurssin asetukset",
"My courses": "Kurssini",
"Attach": "Attach",
"Home": "Projektin kotisivu",

@ -3,7 +3,6 @@
"Links": "Leinkjur",
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"My courses": "M\u00edni skei\u00f0",
"Attach": "Attach",
"Home": "Heim",

@ -18,7 +18,7 @@
"Surveys": "Enqu\u00eates",
"Tracking": "Tracking",
"Course maintenance": "Maintenance du cours",
"Course setting": "Course setting",
"Course settings": "Param\u00e8tres du cours",
"Sign in": "Connectez-vous",
"My courses": "Mes cours",
"Start recording": "Lancer l'enregistrement",
@ -447,7 +447,7 @@
"Cancel": "Annuler",
"Event": "Event",
"Are you sure you want to delete this event?": "Are you sure you want to delete this event?",
"Edit introduction": "Edit introduction",
"Edit introduction": "\u00c9diter l'introduction",
"Show all": "Afficher tout",
"Hide all": "Masquer tout",
"Sort": "Trier",

@ -18,7 +18,7 @@
"Surveys": "Surveys",
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"Course settings": "Course settings",
"Sign in": "Sign in",
"My courses": "My courses",
"Start recording": "Start recording",

@ -18,7 +18,7 @@
"Surveys": "Surveys",
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"Course settings": "Course settings",
"Sign in": "Sign in",
"My courses": "My courses",
"Start recording": "Start recording",

@ -18,7 +18,7 @@
"Surveys": "\u05e1\u05e7\u05e8\u05d9\u05dd",
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"Course settings": "\u05d4\u05d2\u05d3\u05e8\u05d5\u05ea \u05e7\u05d5\u05e8\u05e1",
"Sign in": "\u05db\u05e0\u05d9\u05e1\u05d4",
"My courses": "\u05d4\u05e7\u05d5\u05e8\u05e1\u05d9\u05dd \u05e9\u05dc\u05d9",
"Start recording": "\u05d4\u05ea\u05d7\u05dc \u05dc\u05d4\u05e7\u05dc\u05d9\u05d8",

@ -1,7 +1,6 @@
{
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"Attach": "Attach",
"Is it editable by the invitees?": "Is it editable by the invitees?",
"Field is required": "Field is required",

@ -12,7 +12,6 @@
"Survey": "Anketa",
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"My courses": "Moji predmeti",
"Attach": "Attach",
"Home": "Po\u010detna stranica",

@ -12,7 +12,6 @@
"Survey": "K\u00e9rd\u0151\u00edv",
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"My courses": "Kurzusaim",
"Attach": "Attach",
"Home": "Kezd\u0151lap",

@ -11,7 +11,6 @@
"Member": "Anggota",
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"My courses": "Daftar Mata Kuliah Ku",
"Attach": "Attach",
"Home": "Home",

@ -18,7 +18,7 @@
"Surveys": "Questionari",
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"Course settings": "Configurazione del modulo",
"Sign in": "Accedi",
"My courses": "Corsi",
"Start recording": "Inizia la registrazione",

@ -13,7 +13,7 @@
"Surveys": "\u610f\u898b\u8abf\u67fb",
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"Course settings": "\u30b3\u30fc\u30b9\u306e\u8a2d\u5b9a",
"My courses": "\u30b3\u30fc\u30b9",
"Attach": "Attach",
"Home": "\u30db\u30fc\u30e0",

@ -1,7 +1,6 @@
{
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"Attach": "Attach",
"Is it editable by the invitees?": "Is it editable by the invitees?",
"Field is required": "Field is required",

@ -8,7 +8,6 @@
"Groups": "\uadf8\ub8f9",
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"My courses": "\ub0b4 \uacfc\uc815",
"Attach": "Attach",
"Home": "\ud648",

@ -12,7 +12,6 @@
"Survey": "Apklausa",
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"My courses": "Mano kursai",
"Attach": "Attach",
"Home": "Pagrindinis puslapis",

@ -18,7 +18,7 @@
"Surveys": "Aptaujas",
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"Course settings": "Kursa iestat\u012bjumi",
"My courses": "Mani kursi",
"Attach": "Attach",
"Home": "Mana profila lapas s\u0101kums",

@ -12,7 +12,6 @@
"Survey": "\u0410\u043d\u043a\u0435\u0442\u0430",
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"My courses": "\u041c\u043e\u0438 \u043a\u0443\u0440\u0441\u0435\u0432\u0438",
"Attach": "Attach",
"Home": "\u041f\u043e\u0447\u0435\u0442\u043e\u043a",

@ -6,7 +6,6 @@
"Groups": "Kumpulan",
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"My courses": "Senarai Subjek",
"Attach": "Attach",
"Is it editable by the invitees?": "Is it editable by the invitees?",

@ -18,7 +18,7 @@
"Surveys": "Enquete",
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"Course settings": "Cursus instellingen",
"Sign in": "Meld aan",
"My courses": "Mijn cursussen",
"Attach": "Attach",

@ -5,7 +5,6 @@
"Link": "Lenke",
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"My courses": "Mine kurs",
"Attach": "Attach",
"Is it editable by the invitees?": "Is it editable by the invitees?",

@ -18,7 +18,7 @@
"Surveys": "Surveys",
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"Course settings": "Course settings",
"Sign in": "Sign in",
"My courses": "My courses",
"Start recording": "Start recording",

@ -18,7 +18,7 @@
"Surveys": "Ankiety",
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"Course settings": "Ustawienia kursu",
"My courses": "Lista moich kurs\u00f3w",
"Attach": "Attach",
"Home": "Strona g\u0142\u00f3wna",

@ -1,7 +1,6 @@
{
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"Attach": "Attach",
"Is it editable by the invitees?": "Is it editable by the invitees?",
"Field is required": "Field is required",

@ -18,7 +18,7 @@
"Surveys": "Pesquisas",
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"Course settings": "Configura\u00e7\u00f5es do curso",
"Sign in": "Entrar",
"My courses": "Cursos",
"Attach": "Attach",

@ -13,7 +13,7 @@
"Survey": "Tapukuy",
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"Course settings": "Configuraci\u00f3n de la lecci\u00f3n",
"My courses": "Noqapaq yachachiykuna",
"Attach": "Attach",
"Home": "Qallariq",

@ -17,7 +17,7 @@
"Surveys": "Sondaje",
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"Course settings": "Setarile cursului",
"Sign in": "Conectare",
"My courses": "Cursurile mele",
"Attach": "Attach",

@ -14,7 +14,6 @@
"Surveys": "\u041e\u043f\u0440\u043e\u0441\u043d\u0438\u043a\u0438",
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"My courses": "\u041c\u043e\u0438 \u043a\u0443\u0440\u0441\u044b",
"Attach": "Attach",
"Home": "\u041d\u0430\u0447\u0430\u043b\u043e (\u0434\u043e\u043c\u043e\u0439)",

@ -18,7 +18,7 @@
"Surveys": "Prieskum",
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"Course settings": "Nastavenie kurzu",
"Sign in": "Prihl\u00e1si\u0165 sa",
"My courses": "Moje kurzy",
"Attach": "Attach",

@ -18,7 +18,7 @@
"Surveys": "Evalvacijski vpra\u0161alniki",
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"Course settings": "Nastavitve te\u010daja",
"Sign in": "Vpi\u0161i",
"My courses": "Moji te\u010daji",
"Start recording": "Pri\u010dni snemanje",

@ -1,7 +1,6 @@
{
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"Attach": "Attach",
"Is it editable by the invitees?": "Is it editable by the invitees?",
"Field is required": "Field is required",

@ -9,7 +9,7 @@
"Groups": "Grupe",
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"Course settings": "Pode\u0161avanje kursa",
"My courses": "Moja lista kurseva",
"Attach": "Attach",
"Home": "Po\u010detak",

@ -14,7 +14,7 @@
"Surveys": "Unders\u00f6kning",
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"Course settings": "Inst\u00e4llningar",
"My courses": "Mina kurser",
"Attach": "Attach",
"Home": "Hem",

@ -1,7 +1,6 @@
{
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"Attach": "Attach",
"Is it editable by the invitees?": "Is it editable by the invitees?",
"Field is required": "Field is required",

@ -10,7 +10,6 @@
"Groups": "\u0e01\u0e25\u0e38\u0e48\u0e21",
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"My courses": "\u0e23\u0e32\u0e22\u0e27\u0e34\u0e0a\u0e32\u0e02\u0e2d\u0e07\u0e40\u0e23\u0e32",
"Attach": "Attach",
"Home": "\u0e2b\u0e19\u0e49\u0e32\u0e41\u0e23\u0e01",

@ -13,7 +13,7 @@
"Surveys": "Mga Sarbey",
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"Course settings": "Mga setting ng kurso",
"My courses": "Aking Mga Kurso",
"Attach": "Attach",
"Home": "Home",

@ -12,7 +12,6 @@
"Member": "\u00dcye",
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"My courses": "Derslerim",
"Attach": "Attach",
"Home": "Ana sayfa",

@ -11,7 +11,6 @@
"Survey": "\u041e\u043f\u0438\u0442\u0443\u0432\u0430\u043d\u043d\u044f",
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"My courses": "\u041c\u043e\u0457 \u043a\u0443\u0440\u0441\u0438",
"Attach": "Attach",
"Home": "\u0414\u043e\u0434\u043e\u043c\u0443",

@ -6,7 +6,6 @@
"Groups": "S\u1eeda Nh\u00f3m",
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"My courses": "Danh m\u1ee5c kho\u00e1 h\u1ecdc",
"Attach": "Attach",
"Is it editable by the invitees?": "Is it editable by the invitees?",

@ -1,7 +1,6 @@
{
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"Attach": "Attach",
"Is it editable by the invitees?": "Is it editable by the invitees?",
"Field is required": "Field is required",

@ -1,7 +1,6 @@
{
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"Attach": "Attach",
"Is it editable by the invitees?": "Is it editable by the invitees?",
"Field is required": "Field is required",

@ -17,7 +17,7 @@
"Surveys": "\u8c03\u67e5",
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"Course settings": "\u8bfe\u7a0b\u8bbe\u7f6e",
"My courses": "\u6211\u7684\u8bfe\u7a0b",
"Attach": "Attach",
"Home": "\u4e3b\u9875",

@ -12,7 +12,6 @@
"Survey": "\u7d71\u8a08\u8abf\u67e5",
"Tracking": "Tracking",
"Course maintenance": "Course maintenance",
"Course setting": "Course setting",
"My courses": "\u6211\u7684\u8ab2\u7a0b",
"Attach": "Attach",
"Home": "\u9996\u9801",

Binary file not shown.

After

Width:  |  Height:  |  Size: 694 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 947 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

@ -311,7 +311,7 @@ $group[] = $form->createElement(
'radio',
'email_alert_to_teacher_on_new_user_in_course',
null,
get_lang('To teachar and tutor'),
get_lang('To teacher and tutor'),
2
);
$group[] = $form->createElement(

File diff suppressed because it is too large Load Diff

@ -3000,47 +3000,9 @@ EOT;
$repo = Container::getQuizRepository();
return $repo->findAllByCourse($course, $session, (string) $search, $active);
// Show courses by active status
/*if (true == $search_all_sessions) {
$conditions = [
'where' => [
$active_sql.' c_id = ? '.$needle_where.$timeConditions => [
$course_id,
$needle,
],
],
'order' => 'title',
];
} else {
if (empty($session_id)) {
$conditions = [
'where' => [
$active_sql.' (session_id = 0 OR session_id IS NULL) AND c_id = ? '.$needle_where.$timeConditions => [
$course_id,
$needle,
],
],
'order' => 'title',
];
} else {
$conditions = [
'where' => [
$active_sql.' (session_id = 0 OR session_id IS NULL OR session_id = ? ) AND c_id = ? '.$needle_where.$timeConditions => [
$session_id,
$course_id,
$needle,
],
],
'order' => 'title',
];
}
}
$table = Database::get_course_table(TABLE_QUIZ_TEST);
return Database::select('*', $table, $conditions);*/
return $repo->findAllByCourse($course, $session, (string) $search, $active)
->getQuery()
->getResult();
}
/**

@ -26,14 +26,9 @@ class Export
/**
* Export tabular data to CSV-file.
*
* @param array $data
* @param string $filename
* @param bool $writeOnly Whether to only write on disk or also send for download
* @param string $enclosure
*
* @return mixed csv raw data | false if no data to export | string file path if success in $writeOnly mode
*/
public static function arrayToCsv($data, $filename = 'export', $writeOnly = false, $enclosure = '"')
public static function arrayToCsv(array $data, string $filename = 'export', bool $writeOnly = false, string $enclosure = '"')
{
if (empty($data)) {
return false;
@ -55,6 +50,44 @@ class Export
return $filePath;
}
/**
* Converts an array of data into a CSV file and optionally sends it for download.
*
* @return string|void Returns the file path if $writeOnly is true, otherwise sends the file for download and exits.
*/
public static function arrayToCsvSimple(array $data, string $filename = 'export', bool $writeOnly = false)
{
$file = api_get_path(SYS_ARCHIVE_PATH) . uniqid('') . '.csv';
$handle = fopen($file, 'w');
if ($handle === false) {
throw new \RuntimeException("Unable to create or open the file: $file");
}
if (is_array($data)) {
foreach ($data as $row) {
$line = '';
if (is_array($row)) {
foreach ($row as $value) {
$line .= '"' . str_replace('"', '""', (string)$value) . '";';
}
}
fwrite($handle, rtrim($line, ';') . "\n");
}
}
fclose($handle);
if (!$writeOnly) {
DocumentManager::file_send_for_download($file, true, $filename . '.csv');
unlink($file);
exit;
}
return $file;
}
/**
* Export tabular data to XLS-file.
*/

@ -220,6 +220,10 @@ class ExtraFieldValue extends Model
$tags = [];
foreach ($tagValues as $tagValue) {
if (is_array($tagValue)) {
$tagValue = reset($tagValue);
}
if (empty($tagValue)) {
continue;
}
@ -338,8 +342,17 @@ class ExtraFieldValue extends Model
break;
case ExtraField::FIELD_TYPE_DATE:
if (is_array($value)) {
if (empty($value)) {
break;
}
$value = reset($value);
}
if (is_string($value) && !empty($value)) {
$d = DateTime::createFromFormat('Y-m-d', $value);
$valid = $d && $d->format('Y-m-d') === $value;
if ($valid) {
$newParams = [
'item_id' => $params['item_id'],
@ -349,6 +362,7 @@ class ExtraFieldValue extends Model
];
$this->save($newParams, $showQuery);
}
}
break;
case ExtraField::FIELD_TYPE_DATETIME:
$d = DateTime::createFromFormat('Y-m-d H:i', $value);

@ -8533,7 +8533,7 @@ class SessionManager
[
'name' => 'title',
'index' => 's.title',
'width' => '160',
'width' => '300',
'align' => 'left',
'search' => 'true',
'searchoptions' => ['sopt' => $operators],
@ -8549,6 +8549,7 @@ class SessionManager
'name' => 'display_start_date',
'index' => 'display_start_date',
'align' => 'left',
'width' => '200',
'search' => 'true',
'searchoptions' => [
'dataInit' => 'date_pick_today',
@ -8559,6 +8560,7 @@ class SessionManager
'name' => 'display_end_date',
'index' => 'display_end_date',
'align' => 'left',
'width' => '200',
'search' => 'true',
'searchoptions' => [
'dataInit' => 'date_pick_one_month',
@ -8579,6 +8581,7 @@ class SessionManager
'name' => 'users',
'index' => 'users',
'align' => 'left',
'width' => '100',
'search' => 'false',
];
@ -8603,6 +8606,7 @@ class SessionManager
'name' => 'status',
'index' => 'status',
'align' => 'left',
'width' => '120',
'search' => 'true',
'stype' => 'select',
// for the bottom bar
@ -8633,7 +8637,7 @@ class SessionManager
[
'name' => 'title',
'index' => 's.title',
'width' => '160',
'width' => '300',
'align' => 'left',
'search' => 'true',
'searchoptions' => ['sopt' => $operators],
@ -8649,6 +8653,7 @@ class SessionManager
'name' => 'display_start_date',
'index' => 'display_start_date',
'align' => 'left',
'width' => '200',
'search' => 'true',
'searchoptions' => [
'dataInit' => 'date_pick_today',
@ -8659,6 +8664,7 @@ class SessionManager
'name' => 'display_end_date',
'index' => 'display_end_date',
'align' => 'left',
'width' => '200',
'search' => 'true',
'searchoptions' => [
'dataInit' => 'date_pick_one_month',
@ -8679,6 +8685,7 @@ class SessionManager
'name' => 'users',
'index' => 'users',
'align' => 'left',
'width' => '100',
'search' => 'false',
];
@ -8722,7 +8729,7 @@ class SessionManager
[
'name' => 'title',
'index' => 's.title',
'width' => '200',
'width' => '300',
'align' => 'left',
'search' => 'true',
'searchoptions' => ['sopt' => $operators],
@ -8731,12 +8738,14 @@ class SessionManager
'name' => 'display_start_date',
'index' => 'display_start_date',
'align' => 'left',
'width' => '200',
'search' => 'true',
'searchoptions' => ['dataInit' => 'date_pick_today', 'sopt' => $date_operators],
],
[
'name' => 'display_end_date',
'index' => 'display_end_date',
'width' => '200',
'align' => 'left',
'search' => 'true',
'searchoptions' => ['dataInit' => 'date_pick_one_month', 'sopt' => $date_operators],
@ -8801,7 +8810,7 @@ class SessionManager
[
'name' => 'title',
'index' => 's.title',
'width' => '160',
'width' => '300',
'align' => 'left',
'search' => 'true',
'searchoptions' => ['sopt' => $operators],
@ -8817,6 +8826,7 @@ class SessionManager
'name' => 'display_start_date',
'index' => 'display_start_date',
'align' => 'left',
'width' => '200',
'search' => 'true',
'searchoptions' => [
'dataInit' => 'date_pick_today',
@ -8827,6 +8837,7 @@ class SessionManager
'name' => 'display_end_date',
'index' => 'display_end_date',
'align' => 'left',
'width' => '200',
'search' => 'true',
'searchoptions' => [
'dataInit' => 'date_pick_one_month',
@ -8847,6 +8858,7 @@ class SessionManager
'name' => 'users',
'index' => 'users',
'align' => 'left',
'width' => '100',
'search' => 'false',
];
@ -8871,6 +8883,7 @@ class SessionManager
'name' => 'status',
'index' => 'status',
'align' => 'left',
'width' => '120',
'search' => 'true',
'stype' => 'select',
// for the bottom bar
@ -10213,4 +10226,192 @@ class SessionManager
return $users;
}
/**
* Method to export sessions data as CSV
*/
public static function exportSessionsAsCSV(array $selectedSessions): void
{
$csvData = [];
$headersGenerated = false;
$csvHeaders = [];
foreach ($selectedSessions as $sessionId) {
$courses = SessionManager::get_course_list_by_session_id($sessionId);
if (!empty($courses)) {
foreach ($courses as $course) {
$courseCode = $course['course_code'];
$courseId = $course['id'];
$studentList = CourseManager::get_student_list_from_course_code(
$courseCode,
true,
$sessionId
);
$userIds = array_keys($studentList);
[$generatedHeaders, $csvContent] = self::generateSessionCourseReportData($sessionId, $courseId, $userIds);
if (!$headersGenerated) {
$csvHeaders = $generatedHeaders;
$headersGenerated = true;
}
foreach ($csvContent as $row) {
$csvData[] = $row;
}
}
}
}
if (!empty($csvData)) {
array_unshift($csvData, $csvHeaders);
$filename = 'export_session_courses_reports_complete_' . date('Y-m-d_H-i-s') . '.csv';
Export::arrayToCsvSimple($csvData, $filename);
exit;
}
}
/**
* Exports session data as a ZIP file with CSVs and sends it for download.
*/
public static function exportSessionsAsZip(array $sessionList): void
{
$tempZipFile = api_get_path(SYS_ARCHIVE_PATH) . api_get_unique_id() . '.zip';
$tempDir = dirname($tempZipFile);
if (!is_dir($tempDir) || !is_writable($tempDir)) {
exit("The directory for creating the ZIP file does not exist or lacks write permissions: $tempDir");
}
$zip = new \ZipArchive();
if ($zip->open($tempZipFile, \ZipArchive::CREATE | \ZipArchive::OVERWRITE) !== true) {
exit("Unable to open the ZIP file for writing: $tempZipFile");
}
foreach ($sessionList as $sessionItemId) {
$courses = SessionManager::get_course_list_by_session_id($sessionItemId);
if (!empty($courses)) {
foreach ($courses as $course) {
$courseCode = $course['course_code'];
$courseId = $course['id'];
$studentList = CourseManager::get_student_list_from_course_code($courseCode, true, $sessionItemId);
$userIds = array_keys($studentList);
[$csvHeaders, $csvContent] = self::generateSessionCourseReportData($sessionItemId, $courseId, $userIds);
array_unshift($csvContent, $csvHeaders);
$sessionInfo = api_get_session_info($sessionItemId);
$courseInfo = api_get_course_info_by_id($courseId);
$csvFileName = $sessionInfo['name'] . '_' . $courseInfo['name'] . '.csv';
$csvFilePath = Export::arrayToCsvSimple($csvContent, $csvFileName, true);
if ($csvFilePath && file_exists($csvFilePath)) {
$zip->addFile($csvFilePath, $csvFileName);
}
}
}
}
if (!$zip->close()) {
exit("Could not close the ZIP file correctly.");
}
if (file_exists($tempZipFile)) {
DocumentManager::file_send_for_download($tempZipFile, true);
unlink($tempZipFile);
} else {
exit("The ZIP file was not created correctly.");
}
}
private static function generateSessionCourseReportData($sessionId, $courseId, $userIds): array
{
$em = Database::getManager();
$sessionRepository = $em->getRepository(Session::class);
$session = $sessionRepository->find($sessionId);
if (!$session instanceof Session) {
throw new \InvalidArgumentException("Invalid session object for session ID $sessionId");
}
$courseInfo = api_get_course_info_by_id($courseId);
$courseCode = $courseInfo['code'];
$csvHeaders = [
get_lang('Session name'),
get_lang('Session access dates'),
get_lang('Session display dates'),
get_lang('Course name'),
get_lang('Official code'),
get_lang('First name'),
get_lang('Last name'),
get_lang('Login'),
get_lang('Training time'),
get_lang('Course progress'),
get_lang('Exercise progress'),
get_lang('Exercise average'),
get_lang('Score'),
get_lang('Score') . ' - ' . get_lang('Best attempt'),
get_lang('Student_publication'),
get_lang('Messages'),
get_lang('Classes'),
get_lang('Registration date'),
get_lang('First login in course'),
get_lang('Latest login in course'),
];
$csvData = TrackingCourseLog::getUserData(
null,
count($userIds),
null,
null,
[],
true,
true,
$courseCode,
$sessionId,
true,
$userIds
);
$rawCsvContent = ChamiloSession::read('csv_content');
if (empty($rawCsvContent)) {
throw new \RuntimeException("No CSV content found in session for course $courseCode and session $sessionId.");
}
$csvContent = [];
foreach ($rawCsvContent as $row) {
$alignedRow = [
$row['session_name'] ?? '',
$row['session_startdate'] ?? '',
$row['session_enddate'] ?? '',
$row['course_name'] ?? '',
$row['official_code'] ?? '',
$row['firstname'] ?? '',
$row['lastname'] ?? '',
$row['username'] ?? '',
$row['time'] ?? '',
$row['average_progress'] ?? '',
$row['exercise_progress'] ?? '',
$row['exercise_average'] ?? '',
$row['student_score'] ?? '',
$row['student_score_best'] ?? '',
$row['count_assignments'] ?? '',
$row['count_messages'] ?? '',
$row['classes'] ?? '',
$row['registered_at'] ?? '',
$row['first_connection'] ?? '',
$row['last_connection'] ?? '',
];
$csvContent[] = $alignedRow;
}
return [$csvHeaders, $csvContent];
}
}

File diff suppressed because it is too large Load Diff

@ -18,6 +18,8 @@ use Chamilo\CoreBundle\Component\Utils\ToolIcon;
*/
class UserGroupModel extends Model
{
public const SOCIAL_CLASS = 1;
public const NORMAL_CLASS = 0;
public $columns = [
'id',
'title',

@ -350,7 +350,7 @@ switch ($action) {
$studentId,
$course,
[],
$sId,
api_get_session_entity($sId),
false,
false,
true

@ -18,9 +18,21 @@ $htmlHeadXtra[] = api_get_jqgrid_js();
$action = $_REQUEST['action'] ?? null;
$idChecked = $_REQUEST['idChecked'] ?? null;
$idMultiple = $_REQUEST['id'] ?? null;
$listType = isset($_REQUEST['list_type']) ? Security::remove_XSS($_REQUEST['list_type']) : SessionManager::getDefaultSessionTab();
$copySessionContent = isset($_REQUEST['copy_session_content']) ? true : false;
switch ($action) {
case 'delete_multiple':
$sessionList = explode(',', $idMultiple);
foreach ($sessionList as $id) {
$sessionInfo = api_get_session_info($id);
if ($sessionInfo) {
$response = SessionManager::delete($id);
}
}
echo 1;
exit;
case 'delete':
$sessionInfo = api_get_session_info($idChecked);
if ($sessionInfo) {
@ -37,7 +49,6 @@ switch ($action) {
}
header('Location: '.$url);
exit();
break;
case 'copy':
$result = SessionManager::copy($idChecked);
if ($result) {
@ -50,6 +61,32 @@ switch ($action) {
$url = 'session_list.php?list_type='.$listType;
}
header('Location: '.$url);
exit;
case 'copy_multiple':
$sessionList = explode(',', $idMultiple);
foreach ($sessionList as $id) {
$sessionIdCopied = SessionManager::copy($id);
if ($sessionIdCopied) {
$sessionInfo = api_get_session_info($sessionIdCopied);
Display::addFlash(Display::return_message(get_lang('ItemCopied').' - '.$sessionInfo['name']));
} else {
Display::addFlash(Display::return_message(get_lang('ThereWasAnError'), 'error'));
}
}
$url = 'session_list.php';
if ('custom' !== $listType) {
$url = 'session_list.php?list_type='.$listType;
}
header('Location: '.$url);
exit;
case 'export_csv':
$selectedSessions = explode(',', $idMultiple);
SessionManager::exportSessionsAsCSV($selectedSessions);
break;
case 'export_multiple':
$sessionList = explode(',', $idMultiple);
SessionManager::exportSessionsAsZip($sessionList);
break;
}
@ -163,6 +200,11 @@ $action_links = 'function action_formatter(cellvalue, options, rowObject) {
$urlAjaxExtraField = api_get_path(WEB_AJAX_PATH).'extra_field.ajax.php?1=1';
$orderUrl = api_get_path(WEB_AJAX_PATH).'session.ajax.php?a=order';
$deleteUrl = api_get_self().'?list_type='.$listType.'&action=delete_multiple';
$copyUrl = api_get_self().'?list_type='.$listType.'&action=copy_multiple';
$exportUrl = api_get_self().'?list_type='.$listType.'&action=export_multiple';
$exportCsvUrl = api_get_self().'?list_type='.$listType.'&action=export_csv';
$extra_params['multiselect'] = true;
?>
<script>
@ -302,12 +344,47 @@ $orderUrl = api_get_path(WEB_AJAX_PATH).'session.ajax.php?a=order';
grid.jqGrid('sortableRows', options);
grid.jqGrid('navGrid','#sessions_pager',
{edit:false,add:false,del:false},
{edit:false,add:false,del:true},
{height:280,reloadAfterSubmit:false}, // edit options
{height:280,reloadAfterSubmit:false}, // add options
{reloadAfterSubmit:false},// del options
{reloadAfterSubmit:true, url: '<?php echo $deleteUrl; ?>' }, // del options
prmSearch
);
).navButtonAdd('#sessions_pager',{
caption:"<?php echo addslashes(Display::return_icon('copy.png', get_lang('Copy'))); ?>",
buttonicon:"ui-icon ui-icon-plus",
onClickButton: function(a) {
var list = $("#sessions").jqGrid('getGridParam', 'selarrrow');
if (list.length) {
window.location.replace('<?php echo $copyUrl; ?>&id='+list.join(','));
} else {
alert("<?php echo addslashes(get_lang('Select an option')); ?>");
}
}
}).navButtonAdd('#sessions_pager',{
caption:"<?php echo addslashes(Display::return_icon('save_pack.png', get_lang('Export courses reports'))); ?>",
buttonicon:"ui-icon ui-icon-plus",
onClickButton: function(a) {
var list = $("#sessions").jqGrid('getGridParam', 'selarrrow');
if (list.length) {
window.location.replace('<?php echo $exportUrl; ?>&id='+list.join(','));
} else {
alert("<?php echo addslashes(get_lang('Select an option')); ?>");
}
},
position:"last"
}).navButtonAdd('#sessions_pager',{
caption:"<?php echo addslashes(Display::return_icon('export_csv.png', get_lang('Export courses reports complete'))); ?>",
buttonicon:"ui-icon ui-icon-plus",
onClickButton: function(a) {
var list = $("#sessions").jqGrid('getGridParam', 'selarrrow');
if (list.length) {
window.location.replace('<?php echo $exportCsvUrl; ?>&id='+list.join(','));
} else {
alert("<?php echo addslashes(get_lang('Select an option')); ?>");
}
},
position:"last"
});
<?php
// Create the searching dialog.

@ -17,6 +17,7 @@ $course = api_get_course_entity();
if (null === $course) {
api_not_allowed(true);
}
$courseInfo = api_get_course_info();
$sessionId = api_get_session_id();
$is_allowedToTrack = Tracking::isAllowToTrack($sessionId);
$session = api_get_session_entity($sessionId);
@ -28,12 +29,23 @@ if (!$is_allowedToTrack) {
//keep course_code form as it is loaded (global) by the table's get_user_data
$courseCode = $course->getCode();
$courseId = $course->getId();
$parameters['cid'] = isset($_GET['cid']) ? (int) $_GET['cid'] : '';
$parameters['id_session'] = $sessionId;
$parameters['from'] = isset($_GET['myspace']) ? Security::remove_XSS($_GET['myspace']) : null;
$parameters['user_active'] = isset($_REQUEST['user_active']) && is_numeric($_REQUEST['user_active']) ? (int) $_REQUEST['user_active'] : null;
// PERSON_NAME_DATA_EXPORT is buggy
$sortByFirstName = api_sort_by_first_name();
$from_myspace = false;
$from = $_GET['from'] ?? null;
$origin = api_get_origin();
$lpShowMaxProgress = 'true' === api_get_setting('lp.lp_show_max_progress_instead_of_average');
if ('true' === api_get_setting('lp.lp_show_max_progress_or_average_enable_course_level_redefinition')) {
$lpShowProgressCourseSetting = api_get_course_setting('lp_show_max_or_average_progress');
if (in_array($lpShowProgressCourseSetting, ['max', 'average'])) {
$lpShowMaxProgress = ('max' === $lpShowProgressCourseSetting);
}
}
// Starting the output buffering when we are exporting the information.
$export_csv = isset($_GET['export']) && 'csv' === $_GET['export'];
@ -80,7 +92,18 @@ if (api_is_drh()) {
}
}
if ($export_csv) {
$additionalParams = '';
if (isset($_GET['additional_profile_field'])) {
foreach ($_GET['additional_profile_field'] as $fieldId) {
$additionalParams .= '&additional_profile_field[]='.(int) $fieldId;
}
}
if (isset($parameters['user_active'])) {
$additionalParams .= '&user_active='.(int) $parameters['user_active'];
}
if ($export_csv || isset($_GET['csv'])) {
if (!empty($sessionId)) {
Session::write('id_session', $sessionId);
}
@ -93,6 +116,13 @@ if (!empty($columnsToHideFromSetting) && isset($columnsToHideFromSetting['column
}
$columnsToHide = json_encode($columnsToHide);
$csv_content = [];
$visibleIcon = Display::return_icon(
'visible.png',
get_lang('HideColumn'),
['align' => 'absmiddle', 'hspace' => '3px']
);
$exportInactiveUsers = api_get_path(WEB_CODE_PATH).'tracking/courseLog.php?'.api_get_cidreq().'&'.$additionalParams;
// Scripts for reporting array hide/show columns
$js = "<script>
@ -129,6 +159,10 @@ $js = "<script>
foldup(id);
});
}
$('#download-csv').on('click', function (e) {
e.preventDefault();
location.href = '".$exportInactiveUsers.'&csv=1&since='."'+$('#reminder_form_since').val();
});
})
</script>";
$htmlHeadXtra[] = $js;
@ -141,6 +175,7 @@ $TABLECOURSE = Database::get_main_table(TABLE_MAIN_COURSE);
$table_user = Database::get_main_table(TABLE_MAIN_USER);
$TABLEQUIZ = Database::get_course_table(TABLE_QUIZ_TEST);
$userEditionExtraFieldToCheck = 'true' === api_get_setting('platform.user_edition_extra_field_to_check');
// Breadcrumbs.
if ('resume_session' === $origin) {
$interbreadcrumb[] = [
@ -195,6 +230,31 @@ if (isset($_GET['additional_profile_field'])) {
Session::write('additional_user_profile_info', $userProfileInfo);
Session::write('extra_field_info', $extra_info);
$defaultExtraFields = [];
$defaultExtraFieldsFromSettings = [];
$defaultExtraFieldsFromSettings = api_get_setting('course.course_log_default_extra_fields', true);
if (!empty($defaultExtraFieldsFromSettings) && isset($defaultExtraFieldsFromSettings['extra_fields'])) {
$defaultExtraFields = $defaultExtraFieldsFromSettings['extra_fields'];
$defaultExtraInfo = [];
$defaultUserProfileInfo = [];
foreach ($defaultExtraFields as $fieldName) {
$extraFieldInfo = UserManager::get_extra_field_information_by_name($fieldName);
if (!empty($extraFieldInfo)) {
// Fetching only the user that are loaded NOT ALL user in the portal.
$defaultUserProfileInfo[$extraFieldInfo['id']] = TrackingCourseLog::getAdditionalProfileInformationOfFieldByUser(
$extraFieldInfo['id'],
$user_ids
);
$defaultExtraInfo[$extraFieldInfo['id']] = $extraFieldInfo;
}
}
Session::write('default_additional_user_profile_info', $defaultUserProfileInfo);
Session::write('default_extra_field_info', $defaultExtraInfo);
}
Display::display_header($nameTools, 'Tracking');
$actionsLeft = TrackingCourseLog::actionsLeft('users', $sessionId, false);
@ -202,13 +262,6 @@ $actionsLeft = TrackingCourseLog::actionsLeft('users', $sessionId, false);
$actionsRight = '<a href="javascript: void(0);" onclick="javascript: window.print();">'.
Display::getMdiIcon(ActionIcon::PRINT, 'ch-tool-icon', null, ICON_SIZE_MEDIUM, get_lang('Print')).'</a>';
$additionalParams = '';
if (isset($_GET['additional_profile_field'])) {
foreach ($_GET['additional_profile_field'] as $fieldId) {
$additionalParams .= '&additional_profile_field[]='.(int) $fieldId;
}
}
$users_tracking_per_page = '';
if (isset($_GET['users_tracking_per_page'])) {
$users_tracking_per_page = '&users_tracking_per_page='.intval($_GET['users_tracking_per_page']);
@ -326,8 +379,10 @@ $class = new UserGroupModel();
//$classes = $class->getUserGroupInCourse($options);
$classes = $class->get_all();
$bestScoreLabel = get_lang('Score').' - '.get_lang('BestAttempt');
// Show the charts part only if there are students subscribed to this course/session
if ($nbStudents > 0) {
if ($nbStudents > 0 || isset($parameters['user_active'])) {
// Classes
$formClass = new FormValidator(
'classes',
@ -456,12 +511,18 @@ if ($nbStudents > 0) {
if (false === $hideReports) {
$conditions['course_id'] = $courseId;
$conditions['include_invited_users'] = false;
$usersTracking = TrackingCourseLog::get_user_data(
$usersTracking = TrackingCourseLog::getUserData(
0,
$nbStudents,
$trackingColumn,
$trackingDirection,
$conditions
$conditions,
true,
false,
null,
(int) $sessionId,
$export_csv,
$user_ids
);
$userRepo = Container::getUserRepository();
foreach ($usersTracking as $userTracking) {
@ -474,7 +535,7 @@ if ($nbStudents > 0) {
$numberStudentsCompletedLP++;
}
$averageStudentTestScore = substr($userTracking[7], 0, -1);
$averageStudentsTestScore += $averageStudentTestScore;
$averageStudentsTestScore .= $averageStudentTestScore;
if ('100' === $averageStudentTestScore) {
$reducedAverage = 9;
@ -574,11 +635,11 @@ if ($nbStudents > 0) {
$el->setSelected(7);
$form->addElement('hidden', 'action', 'add');
$form->addElement('hidden', 'remindallinactives', 'true');
$form->addElement('hidden', 'cidReq', $course->getCode());
$form->addElement('hidden', 'id_session', api_get_session_id());
$form->addElement('hidden', 'cid', api_get_course_int_id());
$form->addElement('hidden', 'sid', api_get_session_id());
$form->addButtonSend(get_lang('Notify'));
$extraFieldSelect = TrackingCourseLog::display_additional_profile_fields();
$extraFieldSelect = TrackingCourseLog::displayAdditionalProfileFields();
if (!empty($extraFieldSelect)) {
$html .= $extraFieldSelect;
}
@ -612,7 +673,7 @@ if ($nbStudents > 0) {
$table->setDataFunctionParams($conditions);
}
$parameters['cidReq'] = isset($_GET['cidReq']) ? Security::remove_XSS($_GET['cidReq']) : '';
$parameters['cid'] = isset($_GET['cid']) ? Security::remove_XSS($_GET['cid']) : '';
$parameters['sid'] = $sessionId;
$parameters['from'] = isset($_GET['myspace']) ? Security::remove_XSS($_GET['myspace']) : null;
@ -718,6 +779,11 @@ if ($nbStudents > 0) {
$headers['first_login'] = get_lang('First access to course');
$table->set_header($headerCounter++, get_lang('Latest access in course'), false);
$headers['latest_login'] = get_lang('Latest access in course');
$table->set_header($headerCounter++, get_lang('Lp Finalization Date'), false);
$headers['lp_finalization_date'] = get_lang('Lp Finalization Date');
$table->set_header($headerCounter++, get_lang('Quiz Finalization Date'), false);
$headers['quiz_finalization_date'] = get_lang('Quiz Finalization Date');
$counter = $headerCounter;
if ('true' === api_get_setting('show_email_addresses')) {
$table->set_header($counter, get_lang('Email'), false);
@ -732,6 +798,15 @@ if ($nbStudents > 0) {
$parameters['additional_profile_field'] = $fieldId;
}
}
if (isset($defaultExtraFields)) {
if (!empty($defaultExtraInfo)) {
foreach ($defaultExtraInfo as $field) {
$table->set_header($counter, $field['display_text'], false);
$headers[$field['variable']] = $field['display_text'];
$counter++;
}
}
}
$table->set_header($counter, get_lang('Details'), false);
$headers['Details'] = get_lang('Details');
@ -742,7 +817,7 @@ if ($nbStudents > 0) {
$parameters[$key] = $value;
}
}
$parameters['cidReq'] = $courseCode;
$parameters['cid'] = api_get_course_int_id();
$parameters['sid'] = $sessionId;
$table->set_additional_parameters($parameters);
// display buttons to un hide hidden columns
@ -783,15 +858,7 @@ $groupTable->setHeaderContents(0, $column++, get_lang('Average time in the cours
$groupTable->setHeaderContents(0, $column++, get_lang('Course progress'));
$groupTable->setHeaderContents(0, $column++, get_lang('Exercise average'));
/*$exerciseList = ExerciseLib::get_all_exercises(
$courseInfo,
$sessionId,
false,
null,
false,
3
);*/
$exerciseList = [];
$session = api_get_session_entity($sessionId);
$qb = Container::getQuizRepository()->findAllByCourse($course, $session, null, 2, false);
/** @var CQuiz[] $exercises */
@ -946,7 +1013,8 @@ if (!empty($groupList)) {
$totalBestScoreAverageNotInLP = 0;
$bestScoreAverageNotInLP = 0;
if (!empty($exercises)) {
foreach ($exercises as $exerciseData) {
foreach ($exercises as $i => $exerciseData) {
$exerciseList[$i]['iid'] = $exerciseData->getIid();
foreach ($studentIdList as $userId) {
$results = Event::get_best_exercise_results_by_user(
$exerciseData->getIid(),
@ -975,6 +1043,13 @@ if (!empty($groupList)) {
2
).' %';
}
$bestScoreAverageNotInLP = (string) TrackingCourseLog::calcBestScoreAverageNotInLP(
$exerciseList,
$studentIdList,
(int) $courseInfo['real_id'],
$sessionId,
true
);
}
$row = 1;
@ -1022,6 +1097,8 @@ if ($export_csv) {
$csv_headers[] = get_lang('First access to course');
$csv_headers[] = get_lang('Latest access in course');
$csv_headers[] = get_lang('Lp Finalization Date');
$csv_headers[] = get_lang('Quiz Finalization Date');
if (isset($_GET['additional_profile_field'])) {
foreach ($_GET['additional_profile_field'] as $fieldId) {
@ -1030,7 +1107,7 @@ if ($export_csv) {
}
ob_end_clean();
$csvContentInSession = Session::read('csv_content');
$csvContentInSession = Session::read('csv_content', []);
// Adding headers before the content.
array_unshift($csvContentInSession, $csv_headers);

@ -28,7 +28,7 @@ if (!$is_allowedToTrack) {
}
if ($export_csv || $exportXls) {
$csvData = TrackingCourseLog::get_item_resources_data(0, 0, '', '');
$csvData = TrackingCourseLog::getItemResourcesData(0, 0, '', '');
array_walk(
$csvData,
function (&$item) {

@ -32,7 +32,7 @@ final class Version20230913162700 extends AbstractMigrationChamilo
$resourceNodeRepo = $this->container->get(ResourceNodeRepository::class);
$q = $this->entityManager->createQuery('SELECT c FROM Chamilo\CoreBundle\Entity\Course c');
$updateConfigurations = [
/*$updateConfigurations = [
['table' => 'c_tool_intro', 'field' => 'intro_text'],
['table' => 'c_course_description', 'field' => 'content'],
['table' => 'c_quiz', 'fields' => ['description', 'text_when_finished']],
@ -48,7 +48,7 @@ final class Version20230913162700 extends AbstractMigrationChamilo
['table' => 'c_survey', 'fields' => ['title', 'subtitle']],
['table' => 'c_survey_question', 'fields' => ['survey_question', 'survey_question_comment']],
['table' => 'c_survey_question_option', 'field' => 'option_text'],
];
];*/
/** @var Course $course */
foreach ($q->toIterable() as $course) {
@ -59,9 +59,9 @@ final class Version20230913162700 extends AbstractMigrationChamilo
continue;
}
foreach ($updateConfigurations as $config) {
/* foreach ($updateConfigurations as $config) {
$this->updateContent($config, $courseDirectory, $courseId, $documentRepo);
}
}*/
$this->updateHtmlContent($courseDirectory, $courseId, $documentRepo, $resourceNodeRepo);
}
@ -155,6 +155,13 @@ final class Version20230913162700 extends AbstractMigrationChamilo
$documentPath = str_replace('/courses/'.$courseDirectory.'/document/', '/', $videoPath);
error_log('Debugging Replace URLs:');
error_log('Full URL: ' . $fullUrl);
error_log('Video Path: ' . $videoPath);
error_log('Actual Course Directory: ' . $actualCourseDirectory);
error_log('Processed Document Path: ' . $documentPath);
/*
$sql = "SELECT iid, path, resource_node_id FROM c_document WHERE c_id = $courseId AND path LIKE '$documentPath'";
$result = $this->connection->executeQuery($sql);
$documents = $result->fetchAllAssociative();
@ -170,7 +177,7 @@ final class Version20230913162700 extends AbstractMigrationChamilo
$contentText = str_replace($matches[0][$index], $replacement, $contentText);
}
}
}
}*/
}
return $contentText;

@ -40,7 +40,9 @@ final class CQuizRepository extends ResourceRepository implements ResourceWithLi
$this->addCategoryQueryBuilder($categoryId, $qb);
$this->addActiveQueryBuilder($active, $qb);
$this->addNotDeletedQueryBuilder($qb);
if (!empty($title)) {
$this->addTitleQueryBuilder($title, $qb);
}
return $qb;
}

@ -27805,3 +27805,24 @@ msgstr "Select the destination folder"
msgid "All users"
msgstr "All users"
msgid "Edit introduction"
msgstr "Edit introduction"
msgid "To teacher and tutor"
msgstr "To teacher and tutor"
msgid "To HR only"
msgstr "To HR only"
msgid "Only for teachers"
msgstr "Only for teachers"
msgid "Only for students"
msgstr "Only for students"
msgid "Autolaunch settings"
msgstr "Autolaunch settings"
msgid "Auto-launch"
msgstr "Auto-launch"

@ -28783,3 +28783,24 @@ msgstr "Seleccione la carpeta de destino"
msgid "All users"
msgstr "Todos los usuarios"
msgid "Edit introduction"
msgstr "Editar la introduccion"
msgid "To teacher and tutor"
msgstr "Para profesor y tutor"
msgid "To HR only"
msgstr "Solo para RRHH"
msgid "Only for teachers"
msgstr "Solo para profesores"
msgid "Only for students"
msgstr "Solo para estudiantes"
msgid "Autolaunch settings"
msgstr "Configuración de inicio automático"
msgid "Auto-launch"
msgstr "Inicio automático"

@ -1812,7 +1812,7 @@ msgid "Course program"
msgstr "Cahier des charges"
msgid "Statistics"
msgstr "Suivi"
msgstr "Statistiques"
msgid "Upload page and link to Home Page"
msgstr "Déposer page et lier à l'accueil"
@ -29585,3 +29585,24 @@ msgstr "Choisir le dossier de destination"
msgid "All users"
msgstr "Tous les utilisateurs"
msgid "Edit introduction"
msgstr "Éditer l'introduction"
msgid "To teacher and tutor"
msgstr "Pour le professeur et le tuteur"
msgid "To HR only"
msgstr "Pour les RH uniquement"
msgid "Only for teachers"
msgstr "Pour les professeurs uniquement"
msgid "Only for students"
msgstr "Pour les apprenants uniquement"
msgid "Autolaunch settings"
msgstr "Paramètres d'auto démarrage"
msgid "Auto-launch"
msgstr "Auto-démarrage"

@ -27791,3 +27791,24 @@ msgstr ""
msgid "All users"
msgstr ""
msgid "Edit introduction"
msgstr ""
msgid "To teacher and tutor"
msgstr ""
msgid "To HR only"
msgstr ""
msgid "Only for teachers"
msgstr ""
msgid "Only for students"
msgstr ""
msgid "Autolaunch settings"
msgstr ""
msgid "Auto-launch"
msgstr ""

Loading…
Cancel
Save