Minor - Merge from 1.11.x

pull/2487/head
jmontoyaa 8 years ago
parent 4826375032
commit 98ef2b54cb
  1. 85
      documentation/changelog.html
  2. 12
      documentation/optimization.html
  3. 3
      documentation/security.html
  4. 1
      main/admin/skill.php
  5. 8
      main/admin/skill_badge_create.php
  6. 86
      main/admin/skill_rel_course.php
  7. 14
      main/course_home/course_home.php
  8. 7
      main/course_info/infocours.php
  9. 1
      main/course_progress/thematic_controller.php
  10. 4
      main/document/document.php
  11. 37
      main/exercise/exercise.class.php
  12. 8
      main/exercise/exercise_show.php
  13. 6
      main/exercise/hotpotatoes_exercise_result.class.php
  14. 6
      main/exercise/upload_exercise.php
  15. 25
      main/forum/forumfunction.inc.php
  16. 127
      main/glossary/index.php
  17. 2
      main/gradebook/gradebook_display_summary.php
  18. 43
      main/gradebook/index.php
  19. 4
      main/gradebook/lib/be/abstractlink.class.php
  20. 17
      main/gradebook/lib/be/category.class.php
  21. 92
      main/gradebook/lib/fe/gradebooktable.class.php
  22. 33
      main/gradebook/lib/gradebook_data_generator.class.php
  23. 11
      main/gradebook/lib/gradebook_result.class.php
  24. 87
      main/gradebook/skill_rel_user.php
  25. 30
      main/inc/ajax/announcement.ajax.php
  26. 1
      main/inc/ajax/document.ajax.php
  27. 12
      main/inc/ajax/exercise.ajax.php
  28. 23
      main/inc/ajax/extra_field.ajax.php
  29. 30
      main/inc/ajax/lp.ajax.php
  30. 7
      main/inc/ajax/model.ajax.php
  31. 125
      main/inc/ajax/skill.ajax.php
  32. 15
      main/lp/aiccItem.class.php
  33. 1
      main/lp/aicc_hacp.php
  34. 1084
      main/lp/learnpath.class.php
  35. 293
      main/lp/learnpathItem.class.php
  36. 1
      main/lp/lp_add_audio.php
  37. 25
      main/lp/lp_ajax_initialize.php
  38. 4
      main/lp/lp_ajax_save_item.php
  39. 16
      main/lp/lp_ajax_start_timer.php
  40. 13
      main/lp/lp_ajax_switch_item.php
  41. 1
      main/lp/lp_ajax_switch_item_toc.php
  42. 14
      main/lp/lp_content.php
  43. 104
      main/lp/lp_controller.php
  44. 18
      main/lp/lp_list.php
  45. 15
      main/lp/lp_nav.php
  46. 2
      main/lp/lp_subscribe_users_to_category.php
  47. 79
      main/lp/lp_update_scorm.php
  48. 25
      main/lp/lp_view.php
  49. 1
      main/lp/openoffice_text_document.class.php
  50. 2
      main/lp/scorm_api.php
  51. 7
      main/mySpace/exercise_category_report.php
  52. 29
      main/mySpace/myStudents.php
  53. 38
      main/notebook/index.php
  54. 35
      main/session/resume_session.php
  55. 16
      main/session/scheduled_announcement.php
  56. 105
      main/session/session_add.php
  57. 4
      main/session/session_list.php
  58. 3
      main/social/home.php
  59. 2
      main/social/my_skills_report.php
  60. 5
      main/social/search.php
  61. 14
      main/survey/create_new_survey.php
  62. 12
      main/survey/fillsurvey.php
  63. 59
      main/survey/pending.php
  64. 5
      main/survey/question.php
  65. 5
      main/survey/reporting.php
  66. 5
      main/survey/survey.download.inc.php
  67. 41
      main/survey/survey.lib.php
  68. 156
      main/survey/surveyUtil.class.php
  69. 6
      main/ticket/assign_tickets.php
  70. 2
      main/ticket/new_ticket.php
  71. 3
      main/tracking/course_log_events.php
  72. 23
      main/tracking/course_log_groups.php
  73. 3
      main/tracking/course_log_resources.php
  74. 3
      main/tracking/course_log_tools.php
  75. 77
      main/tracking/messages.php
  76. 20
      main/upload/form.document.php
  77. 38
      main/upload/form.scorm.php
  78. 8
      main/upload/upload_ppt.php
  79. 17
      main/upload/upload_word.php
  80. 17
      main/user/add_users_to_session.php
  81. 4
      main/user/classes.php
  82. 3
      main/user/resume_session.php
  83. 15
      main/work/add_user.php
  84. 7
      main/work/download.php
  85. 33
      main/work/downloadfolder.inc.php
  86. 9
      main/work/upload_corrections.php
  87. 397
      main/work/work.lib.php
  88. 4
      main/work/work.php
  89. 109
      main/work/work_list.php
  90. 5
      main/work/work_list_all.php
  91. 5
      main/work/work_list_others.php
  92. 6
      main/work/work_missing.php

@ -111,6 +111,29 @@
<table class="table" id="index">
</table>
<div class="version" aria-role="article" aria-label="1.11.8">
<a name="1.11.8"></a>
<h1>Chamilo 1.11.8 - ??????, ??/??/????</h1>
<h3>Release notes - summary</h3>
<p>Chamilo 1.11.8 is a minor, bugfix release on top of 1.11.6.</p>
<h3>Release name</h3>
<p>?????????????</p>
<h3>Security fixes</h3>
<h3>Possibly breaking changes</h3>
<h3>Notable new Features</h3>
<h4>For end-users, teachers and Chamilo admins</h4>
<h4>For developers and sysadmins</h4>
<ul>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/604950ff544088ee30632b9a85857cfee2adbc1d">604950ff</a>) Don't clear class for audio/video when removing xss - refs BT#14026 </li>
</ul>
<h3>Improvements (minor features) and debug</h3>
<h3>Stylesheets and theming</h3>
<h3>Web services</h3>
<h3>Removals</h3>
<h3>Known issues</h3>
</div>
<div class="version" aria-role="article" aria-label="1.11.6">
<a name="1.11.6"></a>
@ -127,9 +150,10 @@
<ul aria-role="log" aria-live="off">
</ul>
<h3>Notable new Features</h3>
<h3>Notable new Features</h3>.
<h4>For end-users, teachers and Chamilo admins</h4>
<ul aria-role="log" aria-live="off">
<li>[2018-01-17] (<a href="https://github.com/chamilo/chamilo-lms/commit/49ba4f6d7b9888928e19a19b331d37925d86c351">49ba4f6d</a>) Plugin: Test2PDF: Add test2pdf plugin to convert exercises to PDF. This plugin can be further cleaned up but works as is.</li>
<li>[2017-12-28] (<a href="https://github.com/chamilo/chamilo-lms/commit/958f1f59b64e4008915350cadaf1e4fb3370f578">958f1f59</a> - <a href="https://github.com/chamilo/chamilo-lms/issues/2229">GH#2229</a>) Document: Add Cloud Files links (and fixes)</li>
<li>[2017-10-16] (<a href="https://github.com/chamilo/chamilo-lms/commit/8700571d786e7d153479bd43b1744676cd75daaf">8700571d</a>) Document: Add webm support in showinframes.php (using jplayer)</li>
<li>[2017-10-10] (<a href="https://github.com/chamilo/chamilo-lms/commit/5039c7b294a15f1109308d2a0a2e53f043b5113b">5039c7b2</a> - <a href="https://task.beeznest.com/issues/13527">BT#13527</a>) Learnpath: Add pdf export button in LP result page</li>
@ -205,6 +229,65 @@
<h3>Improvements (minor features) and debug</h3>
<ul aria-role="log" aria-live="off">
<li>[2018-01-18] (<a href="https://github.com/chamilo/chamilo-lms/commit/d713cbff9ff1ebceb4c0e90ecb8131bcf04763cd">d713cbff</a>) Add LTI plugin translation to French and Spanish</li>
<li>[2018-01-18] (<a href="https://github.com/chamilo/chamilo-lms/commit/002b907867dcea704c0533b85c3876a91e393e97">002b9078</a> - <a href="https://task.beeznest.com/issues/13469">BT#13469</a>) Fix and improve Ims/LIT plugin</li>
<li>[2018-01-18] (<a href="https://github.com/chamilo/chamilo-lms/commit/e40687261466e8b5a8173db9e62c7c5faa3b5d97">e4068726</a>) Style: Fix dropdown menu color</li>
<li>[2018-01-18] (<a href="https://github.com/chamilo/chamilo-lms/commit/20482534a3e640f7170949786e9f56b83cd23851">20482534</a> - <a href="https://task.beeznest.com/issues/13885">BT#13885</a>) Chat: Fix Send button in course chat</li>
<li>[2018-01-18] (<a href="https://github.com/chamilo/chamilo-lms/commit/dc70f282cb372a77d4d60abdfce39adcab4187bf">dc70f282</a> - <a href="https://github.com/chamilo/chamilo-lms/issues/2343">GH#2343</a>) Quiz: Fix question pool when filter by session using api_get_session_condition</li>
<li>[2018-01-18] (<a href="https://github.com/chamilo/chamilo-lms/commit/8b9e8517858387e63a59a2fa1228e55572299b97">8b9e8517</a> - <a href="https://github.com/chamilo/chamilo-lms/issues/2268">GH#2268</a>) Display: Fix course progress invisible by default bug</li>
<li>[2018-01-18] (<a href="https://github.com/chamilo/chamilo-lms/commit/ae5a2c11c2349515d8fb83c2f7a7625757c2a3c1">ae5a2c11</a> - <a href="https://task.beeznest.com/issues/13886">BT#13886</a>) Internal: Fix URL redirection when saving course settings</li>
<li>[2018-01-18] (<a href="https://github.com/chamilo/chamilo-lms/commit/535f3815a5baddecb1af915083d04f155576ffcd">535f3815</a> - <a href="https://github.com/chamilo/chamilo-lms/issues/2341">GH#2341</a>) Gradebook: Add certificate=true in links</li>
<li>[2018-01-17] (<a href="https://github.com/chamilo/chamilo-lms/commit/246dfdcfc9ad302bb61d910aefe68cbb46d470fe">246dfdcf</a> - <a href="https://task.beeznest.com/issues/13885">BT#13885</a>) Chat: Tutors only can chat with students when course_chat_restrict_to_coach is enabled</li>
<li>[2018-01-17] (<a href="https://github.com/chamilo/chamilo-lms/commit/f180a4c98bc68187482d959394387359c5d10b49">f180a4c9</a> - <a href="https://task.beeznest.com/issues/13887">BT#13887</a>) Skill : Remove . from language variable names to avoid breakdown</li>
<li>[2018-01-17] (<a href="https://github.com/chamilo/chamilo-lms/commit/29465ed4b1770ecd37a79bf5e65b43f0d6379a98">29465ed4</a> - <a href="https://task.beeznest.com/issues/13885">BT#13885</a>) Chat: Add option to restrict course chat only for coaches</li>
<li>[2018-01-17] (<a href="https://github.com/chamilo/chamilo-lms/commit/49bb2540d9a3b69649e4ed8bc724d5fb5a5270ad">49bb2540</a> - <a href="https://github.com/chamilo/chamilo-lms/issues/2214">GH#2214</a>) Install: Fix issue in update process not removing deprecated paths</li>
<li>[2018-01-17] (<a href="https://github.com/chamilo/chamilo-lms/commit/5c2549a6d945162a797963d93335736dfe530ab1">5c2549a6</a> - <a href="https://github.com/chamilo/chamilo-lms/issues/2214">GH#2214</a>) Instlal: Allow continue installation if deprecated folder exists - Folders will be deleted afterwards.</li>
<li>[2018-01-17] (<a href="https://github.com/chamilo/chamilo-lms/commit/dd3e3e1a0275d57fa34f8048558978eea51c35a3">dd3e3e1a</a> - <a href="https://github.com/chamilo/chamilo-lms/issues/2332">GH#2332</a>) Gradebook: Fix generated certificate redirection</li>
<li>[2018-01-17] (<a href="https://github.com/chamilo/chamilo-lms/commit/342c7efd7a4d768d337520d7cd7f128fd2b378b7">342c7efd</a> - <a href="https://github.com/chamilo/chamilo-lms/issues/2333">GH#2333</a>) Gradebook: Fix edit document, content not updated</li>
<li>[2018-01-17] (<a href="https://github.com/chamilo/chamilo-lms/commit/338161b1ac87967012c4ecfe327da86b3809b314">338161b1</a> - <a href="https://github.com/chamilo/chamilo-lms/issues/2306">GH#2306</a>) Admin: Fix filter by session in course list</li>
<li>[2018-01-17] (<a href="https://github.com/chamilo/chamilo-lms/commit/af0cbeb0adf18bd022e93c3324eb4add7274c623">af0cbeb0</a> - <a href="https://github.com/chamilo/chamilo-lms/issues/2269">GH#2269</a>) Forum: Fix wrong forum link when using it inside a course group</li>
<li>[2018-01-17] (<a href="https://github.com/chamilo/chamilo-lms/commit/1d5c7a35b345264be3694afaeea03c34959223db">1d5c7a35</a> - <a href="https://github.com/chamilo/chamilo-lms/issues/2268">GH#2268</a>) Admin: Hide tool shortcut when it's hidden from teachers</li>
<li>[2018-01-16] (<a href="https://github.com/chamilo/chamilo-lms/commit/d9e1148e4de300f6bb333a0a4a7d3fc508436b71">d9e1148e</a> - <a href="https://task.beeznest.com/issues/13856">BT#13856</a>) Fix export PDF from HTML with /main/img paths</li>
<li>[2018-01-16] (<a href="https://github.com/chamilo/chamilo-lms/commit/48b85ad6dc01bc61cca608c7a1430b9a0111c560">48b85ad6</a> - <a href="https://github.com/chamilo/chamilo-lms/issues/2331">GH#2331</a>) Survey: Fix issue with URL params' "&" filtering</li>
<li>[2018-01-16] (<a href="https://github.com/chamilo/chamilo-lms/commit/984291c44913939311b37ce885d32f0213d8f65a">984291c4</a> - <a href="https://github.com/chamilo/chamilo-lms/issues/2331">GH#2331</a>) Survey: Fix issue updating all users from survey profile form</li>
<li>[2018-01-16] (<a href="https://github.com/chamilo/chamilo-lms/commit/1444f088639aa378b1e2718e274336974cf7eed6">1444f088</a>) Internal: Update user_id to id in user profile edition</li>
<li>[2018-01-16] (<a href="https://github.com/chamilo/chamilo-lms/commit/5695089790c37f2886d690d1d77c6c25255b3286">56950897</a> - <a href="https://task.beeznest.com/issues/13872">BT#13872</a>) Display: Improve title/tooltip for date and datetime pickers</li>
<li>[2018-01-16] (<a href="https://github.com/chamilo/chamilo-lms/commit/f5870090043667be95f36793a98486b694d46a92">f5870090</a> - <a href="https://task.beeznest.com/issues/13870">BT#13870</a>) Survey: Add id_session when sending link in survey</li>
<li>[2018-01-16] (<a href="https://github.com/chamilo/chamilo-lms/commit/5a21e6c568defc12835dc228901e17dd1bc2c47f">5a21e6c5</a> - <a href="https://task.beeznest.com/issues/13870">BT#13870</a>) Survey: Fix php notice + fix "additional email" sent in survey</li>
<li>[2018-01-16] (<a href="https://github.com/chamilo/chamilo-lms/commit/eb2eb66d6882b2ad12f42e8df9b3462f8a72456f">eb2eb66d</a> - <a href="https://task.beeznest.com/issues/13870">BT#13870</a>) Survey: Fix form link, to avoid "not allowed" message in fill survey</li>
<li>[2018-01-16] (<a href="https://github.com/chamilo/chamilo-lms/commit/ecd72c7b6f1ea9c81052e38836af465ab6f4dbae">ecd72c7b</a> - <a href="https://task.beeznest.com/issues/13870">BT#13870</a>) Survey: Fix Fatal error: Uncaught Error: [] operator not supported for strings</li>
<li>[2018-01-16] (<a href="https://github.com/chamilo/chamilo-lms/commit/69bb131699127c687f7713343fb9f77410c40a9c">69bb1316</a> - <a href="https://task.beeznest.com/issues/13870">BT#13870</a>) Survey: Fix get session id when getting survey</li>
<li>[2018-01-15] (<a href="https://github.com/chamilo/chamilo-lms/commit/a3e18eed59419cd965bec9132b4813b79be9de14">a3e18eed</a> - <a href="https://task.beeznest.com/issues/13469">BT#13469</a>) Plugin: WIP - Improving LTI plugin</li>
<li>[2018-01-15] (<a href="https://github.com/chamilo/chamilo-lms/commit/16d13b7a070c6041642fed2c9854a4e4f215f8e7">16d13b7a</a> - <a href="https://task.beeznest.com/issues/13872">BT#13872</a>) Display: Change icon from datetime and date pickers</li>
<li>[2018-01-15] (<a href="https://github.com/chamilo/chamilo-lms/commit/4cc1ce0570bdb26233707d97aa0a9ba9784adf78">4cc1ce05</a> - <a href="https://task.beeznest.com/issues/13870">BT#13870</a>) Survey: Add session id in URL to fix survey error</li>
<li>[2018-01-15] (<a href="https://github.com/chamilo/chamilo-lms/commit/e7f7264248672f97282dc597a1319d9c7fee4798">e7f72642</a> - <a href="https://task.beeznest.com/issues/13870">BT#13870</a>) Survey: Fix fill survey when no invitation sent</li>
<li>[2018-01-12] (<a href="https://github.com/chamilo/chamilo-lms/commit/2a4f588a9326b6a3b826da0a99be7006ea66bef4">2a4f588a</a>) Display: Fix kiddy CSS</li>
<li>[2018-01-12] (<a href="https://github.com/chamilo/chamilo-lms/commit/fdbf575e43ee88159258d709711fec1c246e48df">fdbf575e</a> - <a href="https://task.beeznest.com/issues/13868">BT#13868</a>) Quiz: Fix "question reviewed text" not loading in exercise_show</li>
<li>[2018-01-11] (<a href="https://github.com/chamilo/chamilo-lms/commit/833cf3b288488020888b824b53fab0003a105328">833cf3b2</a>) Learnpath: Add message when file not found in download_scorm.php</li>
<li>[2018-01-11] (<a href="https://github.com/chamilo/chamilo-lms/commit/6b50f0ffaf43c4de8779aeca61b230f327ec5ec6">6b50f0ff</a> - <a href="https://task.beeznest.com/issues/13818">BT#13818</a>) Learnpath: Add response code "404 if file not found by SCORM package</li>
<li>[2018-01-11] (<a href="https://github.com/chamilo/chamilo-lms/commit/fd572ef684beaa8c84f7a2e738893952b87e11fb">fd572ef6</a> - <a href="https://task.beeznest.com/issues/13861">BT#13861</a>) Plugin: BBB: Fix BBB when creating a new meeting, remove loop.</li>
<li>[2018-01-09] (<a href="https://github.com/chamilo/chamilo-lms/commit/ffe59354c4774707303cff1810f8ee6efd333f21">ffe59354</a> - <a href="https://github.com/chamilo/chamilo-lms/issues/2301">GH#2301</a>) Tracking: Fix sort user list in tracking tool</li>
<li>[2018-01-09] (<a href="https://github.com/chamilo/chamilo-lms/commit/472c5eaa2dfb686dafbd1e14d14aaad1af529ef3">472c5eaa</a> - <a href="https://github.com/chamilo/chamilo-lms/issues/2160">GH#2160</a>) Quiz: Improve code to show test question categories</li>
<li>[2018-01-09] (<a href="https://github.com/chamilo/chamilo-lms/commit/ae6494f66062f123764b5cc206a60a06171d578a">ae6494f6</a>) Internal: Fix query not working with symfony/doctrine container (master)</li>
<li>[2018-01-09] (<a href="https://github.com/chamilo/chamilo-lms/commit/5eddfed6b8d8fad5257763366feb1f429a639b2a">5eddfed6</a> - <a href="https://task.beeznest.com/issues/13848">BT#13848</a>) Display: Fix course tool order query</li>
<li>[2018-01-08] (<a href="https://github.com/chamilo/chamilo-lms/commit/0ae6fa97127d2ff70ae95c92d8ba0cd1212724fc">0ae6fa97</a> - <a href="https://task.beeznest.com/issues/13756">BT#13756</a>) Display: Add function to show the tutors/teachers names through Twig</li>
<li>[2018-01-08] (<a href="https://github.com/chamilo/chamilo-lms/commit/20c57607302695dd86fb0fbf1682012d0c47586a">20c57607</a>) Display: Delete footer duplicate</li>
<li>[2018-01-08] (<a href="https://github.com/chamilo/chamilo-lms/commit/562085fb4d51af3c70e0ca7545369ddc24bef0c0">562085fb</a> - <a href="https://task.beeznest.com/issues/13602">BT#13602</a>) Announcement: Fix announcement delete action</li>
<li>[2018-01-05] (<a href="https://github.com/chamilo/chamilo-lms/commit/fcab01da8ed495e0bede9bb6614db31d5cf56423">fcab01da</a> - <a href="https://task.beeznest.com/issues/13756">BT#13756</a>) Catalogue: Fix date range to search sessions</li>
<li>[2018-01-05] (<a href="https://github.com/chamilo/chamilo-lms/commit/3900fd2ada83346c06032a286aea6e98a1a47d1f">3900fd2a</a> - <a href="https://task.beeznest.com/issues/13838">BT#13838</a>) Display: Fix web page after registration</li>
<li>[2018-01-05] (<a href="https://github.com/chamilo/chamilo-lms/commit/5d1fc769023bc2edfcf16c99b95353a7ed73f060">5d1fc769</a> - <a href="https://task.beeznest.com/issues/13838">BT#13838</a>) Display: Add Bootstrap style for link inside alert</li>
<li>[2018-01-05] (<a href="https://github.com/chamilo/chamilo-lms/commit/f26113ecd83ab3b38a9b33b80911e4d8f482c92c">f26113ec</a> - <a href="https://task.beeznest.com/issues/13838">BT#13838</a>) Catalogue: Show sign-up button only when allow_registration setting is false</li>
<li>[2018-01-05] (<a href="https://github.com/chamilo/chamilo-lms/commit/6fa2955a1c5a57f7837f408d0bdac2a6208ad293">6fa2955a</a>) Internal: Add constant WEB_PLUGIN_ASSET_PATH (used in v2)</li>
<li>[2018-01-05] (<a href="https://github.com/chamilo/chamilo-lms/commit/3a30ed1c7c7adb290e1a6eb94749ba6e05c31694">3a30ed1c</a> - <a href="https://github.com/chamilo/chamilo-lms/issues/2275">GH#2275</a>) Internal: Add use of session namespace to learnpath item view</li>
<li>[2018-01-04] (<a href="https://github.com/chamilo/chamilo-lms/commit/c9257e83ec3efeec55703e84dba1bea29c056940">c9257e83</a> - <a href="https://task.beeznest.com/issues/13834">BT#13834</a>) Gradebook: Fix cache paths when exporting to pdf</li>
<li>[2018-01-04] (<a href="https://github.com/chamilo/chamilo-lms/commit/95732f801d8e8663052ba9b8de6ed7bd75f88aa0">95732f80</a> - <a href="https://github.com/chamilo/chamilo-lms/issues/2275">GH#2275</a>) Learnpath: Fix menu display error</li>
<li>[2018-01-03] (<a href="https://github.com/chamilo/chamilo-lms/commit/4f04c164606cd5e09c8b6b6a6300f1573cdb9ba9">4f04c164</a>) Admin : add notice_block to the elements to be sent to the layout tpl</li>
<li>[2018-01-03] (<a href="https://github.com/chamilo/chamilo-lms/commit/b12b7e5676c27e17b31ee4122afb8642e644bf45">b12b7e56</a> - <a href="https://task.beeznest.com/issues/13587">BT#13587</a>) Skill: Add "table_of_hierarchical_skill_presentation"</li>
<li>[2018-01-02] (<a href="https://github.com/chamilo/chamilo-lms/commit/6f2c2de6349a2801ae33b8143e04ac5a1b25f6f0">6f2c2de6</a>) Ticket: improve icons</li>
<li>[2018-01-02] (<a href="https://github.com/chamilo/chamilo-lms/commit/aa55ffb18295092fa1086a7c1cc3dbc1c82debfd">aa55ffb1</a>) Display: Show/hide teacher info depending of setting "display_teacher_in_courselist"</li>
<li>[2017-12-30] (<a href="https://github.com/chamilo/chamilo-lms/commit/faf0d7e528a06575d47b7180686b81cee5a79238">faf0d7e5</a> - <a href="https://github.com/chamilo/chamilo-lms/issues/2265">GH#2265</a>) Global: Allow audio tag works with htmlpurifier</li>
<li>[2017-12-29] (<a href="https://github.com/chamilo/chamilo-lms/commit/6555d8f1f2a595e14b65b30c47cb1de1403a2bce">6555d8f1</a> - <a href="https://github.com/chamilo/chamilo-lms/issues/2261">GH#2261</a>) Learnpath: Fix hide left column in LP</li>
<li>[2017-12-28] (<a href="https://github.com/chamilo/chamilo-lms/commit/b9e9ac47280576154c1920d0e36a9975ffbc7d8d">b9e9ac47</a> - <a href="https://github.com/chamilo/chamilo-lms/issues/2149">GH#2149</a>) Webservice: Rename methods saveNewCourse() and saveNewUser() to addCourse() and addUser() in restApi (missing part)</li>
<li>[2017-12-28] (<a href="https://github.com/chamilo/chamilo-lms/commit/c94f7cf2f92799d27ca5140d7f7461c2c3ca15b1">c94f7cf2</a> - <a href="https://task.beeznest.com/issues/13822">BT#13822</a>) Learnpath: Fix issue in comparing document path with code path in document source validation before iframe</li>
<li>[2017-12-28] (<a href="https://github.com/chamilo/chamilo-lms/commit/c7327e9f622ed59ff3fcf6f4bfbe7995851fc5d1">c7327e9f</a> - <a href="https://github.com/chamilo/chamilo-lms/issues/2214">GH#2214</a>) Install: Remove minor query blocking migration (intra-version)</li>
<li>[2017-12-28] (<a href="https://github.com/chamilo/chamilo-lms/commit/d7c55369092023505ac15a0d56b6c54338e53d34">d7c55369</a> - <a href="https://github.com/chamilo/chamilo-lms/issues/2149">GH#2149</a>) Webservice: Rename methods saveNewCourse() and saveNewUser() to addCourse() and addUser() in restApi</li>

@ -195,7 +195,17 @@ ALTER TABLE c_lp_item_view ADD INDEX idx_clpiv_c_i_v (c_id, id, view_count);
find out about these possible bottlenecks after we release stable versions of Chamilo. This is why we list those
queries here. However, as soon as we confirm them with a few real life scenarios, we add them into the core of
Chamilo so you can benefit from them immediately by installing a new version.
<p>In Chamilo 1.11.x you can boost the DB tables related surveys invitations by adding the following indexes:</p>
<pre>
CREATE INDEX idx_survey_q_qid ON c_survey_question (question_id);
CREATE INDEX idx_survey_code ON c_survey (code);
CREATE INDEX idx_survey_inv_code ON c_survey_invitation (survey_code);
CREATE INDEX idx_survey_qo_qid ON c_survey_question_option (question_id);
</pre>
Also by adding a index on access_url_rel_session to improve the course/session list
<pre>
CREATE INDEX idx_accessurs_sid ON access_url_rel_session (session_id);
</pre>
<hr />
<h2><a name="3.Indexes-caching"></a>3. Indexes caching</h2>
One good reference: <a href="http://dev.mysql.com/doc/refman/5.6/en/multiple-key-caches.html">MySQL documentation on multiple key caches</a><br />

@ -10,6 +10,7 @@
<body>
<div class="container">
<h1>Chamilo LMS: Security Guide</h1>
<a href="index.html">Documentation</a> &gt; Security Guide
<p>We recommend you don't take security issues too lightly. Chamilo is security-audited at least once a year,
@ -85,7 +86,7 @@ This will prevent direct access to your settings and make it seem totally the sa
<p>Don't hesitate to hire an experienced administrator to do that,
it might be a bit more expensive now, but you'll be happy not to have to loose
all of your data to a hacker who attacked your site.</p>
<p>Only the following directories have required (or optional) write
<p>Only the following directories have required (or optional) write
permissions from the web server:<br />
<ul>
<li>app/cache/</li>

@ -64,7 +64,6 @@ switch ($action) {
if ($form->validate()) {
$values = $form->exportValues();
$profile = $em->getRepository('ChamiloSkillBundle:Profile')->find($values['profile_id']);
if ($profile) {
$item->setProfile($profile);

@ -89,11 +89,9 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
exit;
}
$interbreadcrumb = [
[
'url' => api_get_path(WEB_CODE_PATH).'admin/index.php',
'name' => get_lang('Administration'),
],
$interbreadcrumb[] = [
'url' => api_get_path(WEB_CODE_PATH).'admin/index.php',
'name' => get_lang('Administration'),
];
$interbreadcrumb[] = ['url' => 'skill_list.php', 'name' => get_lang('ManageSkills')];

@ -0,0 +1,86 @@
<?php
/* For licensing terms, see /license.txt */
use Chamilo\SkillBundle\Entity\SkillRelCourse;
$cidReset = true;
require_once __DIR__.'/../inc/global.inc.php';
if (api_get_configuration_value('allow_skill_rel_items') == false) {
api_not_allowed(true);
}
$courseId = isset($_GET['course_id']) ? (int) $_GET['course_id'] : 0;
$course = api_get_course_entity($courseId);
if (empty($course)) {
api_not_allowed(true);
}
$sessionId = isset($_GET['session_id']) ? (int) $_GET['session_id'] : null;
$url = api_get_self().'?course_id='.$courseId.'&session_id='.$sessionId;
$form = new FormValidator('skills', 'post', $url);
$sessionName = $course->getTitleAndCode();
if (!empty($sessionId)) {
$session = api_get_session_entity($sessionId);
$courseExistsInSession = SessionManager::sessionHasCourse($sessionId, $course->getCode());
if (!$courseExistsInSession) {
api_not_allowed(true);
}
$sessionName = ' '.$session->getName().' - '.$course->getTitleAndCode();
}
$form->addHeader(get_lang('AddSkills').$sessionName);
$skillList = [];
$em = Database::getManager();
$items = $em->getRepository('ChamiloSkillBundle:SkillRelCourse')->findBy(
['course' => $courseId, 'session' => $sessionId]
);
/** @var SkillRelCourse $skillRelCourse */
foreach ($items as $skillRelCourse) {
$skillList[$skillRelCourse->getSkill()->getId()] = $skillRelCourse->getSkill()->getName();
}
$form->addHidden('course_id', $courseId);
$form->addHidden('session_id', $sessionId);
$form->addSelectAjax(
'skills',
get_lang('Skills'),
$skillList,
[
'url' => api_get_path(WEB_AJAX_PATH).'skill.ajax.php?a=search_skills',
'multiple' => 'multiple',
]
);
$form->addButtonSave(get_lang('Save'));
$form->setDefaults(['skills' => array_keys($skillList)]);
if ($form->validate()) {
$result = Skill::saveSkillsToCourseFromForm($form);
if ($result) {
Display::addFlash(Display::return_message(get_lang('Updated')));
}
header('Location: '.$url);
exit;
}
$content = $form->returnForm();
$interbreadcrumb[] = [
'url' => api_get_path(WEB_CODE_PATH).'session/session_list.php',
'name' => get_lang('SessionList'),
];
$interbreadcrumb[] = [
'url' => api_get_path(WEB_CODE_PATH).'session/resume_session.php?id_session='.$sessionId,
'name' => get_lang('SessionOverview'),
];
$template = new Template(get_lang('SkillRelCourses'));
$template->assign('content', $content);
$template->display_one_col_template();

@ -331,6 +331,13 @@ if ($allow === true) {
$content = '<div id="course_tools">'.$diagram.$content.'</div>';
// Deleting the objects
Session::erase('_gid');
Session::erase('oLP');
Session::erase('lpobject');
api_remove_in_gradebook();
DocumentManager::removeGeneratedAudioTempFile();
$tpl = new Template(null);
$tpl->assign('message', $show_message);
$tpl->assign('content', $content);
@ -338,10 +345,3 @@ $tpl->assign('content', $content);
// Direct login to course
$tpl->assign('course_code', $course_code);
$tpl->display_one_col_template();
// Deleting the objects
Session::erase('_gid');
Session::erase('oLP');
Session::erase('lpobject');
api_remove_in_gradebook();
DocumentManager::removeGeneratedAudioTempFile();

@ -504,6 +504,13 @@ if ($allowLPReturnLink === 'true') {
get_lang('RedirectToCourseHome'),
0
),
$form->createElement(
'radio',
'lp_return_link',
null,
get_lang('MyCourses'),
2
),
];
$form->addGroup($group, '', [get_lang("LpReturnLink")]);
}

@ -460,7 +460,6 @@ class ThematicController
$data['default_thematic_plan_icon'] = $thematic->get_default_thematic_plan_icon();
$data['default_thematic_plan_question'] = $thematic->get_default_question();
$data['next_description_type'] = $thematic->get_next_description_type($_POST['thematic_id']);
// render to the view
$this->view->set_data($data);
$this->view->set_layout('layout');

@ -2097,10 +2097,6 @@ if (count($documentAndFolders) > 1) {
$form_action['set_invisible'] = get_lang('SetInvisible');
$form_action['set_visible'] = get_lang('SetVisible');
$form_action['delete'] = get_lang('Delete');
/*$portfolio_actions = Portfolio::actions();
foreach ($portfolio_actions as $action) {
$form_action[$action->get_name()] = $action->get_title();
}*/
$table->set_form_actions($form_action, 'ids');
}
}

@ -5869,19 +5869,22 @@ class Exercise
}
/**
* @param array $user_data result of api_get_user_info()
* @param string $start_date
* @param null $duration
* @param string $ip Optional. The user IP
* @param array $user_data result of api_get_user_info()
* @param array $trackExerciseInfo result of get_stat_track_exercise_info
*
* @return string
*/
public function show_exercise_result_header(
public function showExerciseResultHeader(
$user_data,
$start_date = null,
$duration = null,
$ip = null
$trackExerciseInfo
) {
$start_date = null;
if (isset($trackExerciseInfo['start_date'])) {
$start_date = api_convert_and_format_date($trackExerciseInfo['start_date']);
}
$duration = isset($trackExerciseInfo['duration_formatted']) ? $trackExerciseInfo['duration_formatted'] : null;
$ip = isset($trackExerciseInfo['user_ip']) ? $trackExerciseInfo['user_ip'] : null;
$array = [];
if (!empty($user_data)) {
$array[] = [
@ -5958,6 +5961,7 @@ class Exercise
* @param int Whether the results are show to the user (0) or not (1)
* @param int Maximum number of attempts (0 if no limit)
* @param int Feedback type
* @param int $propagateNegative
*
* @todo this was function was added due the import exercise via CSV
*
@ -6630,21 +6634,12 @@ class Exercise
$new_array = [];
if (Database::num_rows($result) > 0) {
$new_array = Database::fetch_array($result, 'ASSOC');
$new_array['duration'] = null;
$start_date = api_get_utc_datetime($new_array['start_date'], true);
$end_date = api_get_utc_datetime($new_array['exe_date'], true);
if (!empty($start_date) && !empty($end_date)) {
$start_date = api_strtotime($start_date, 'UTC');
$end_date = api_strtotime($end_date, 'UTC');
if ($start_date && $end_date) {
$mytime = $end_date - $start_date;
$new_learnpath_item = new learnpathItem(null);
$time_attemp = $new_learnpath_item->get_scorm_time('js', $mytime);
$h = get_lang('h');
$time_attemp = str_replace('NaN', '00'.$h.'00\'00"', $time_attemp);
$new_array['duration'] = $time_attemp;
}
$new_array['duration_formatted'] = '';
if (!empty($new_array['exe_duration']) && !empty($start_date) && !empty($end_date)) {
$time = api_format_time($new_array['exe_duration'], 'js');
$new_array['duration_formatted'] = $time;
}
}

@ -35,7 +35,6 @@ if (empty($track_exercise_info)) {
}
$exercise_id = $track_exercise_info['id'];
$exercise_date = $track_exercise_info['start_date'];
$student_id = $track_exercise_info['exe_user_id'];
$learnpath_id = $track_exercise_info['orig_lp_id'];
$learnpath_item_id = $track_exercise_info['orig_lp_item_id'];
@ -123,7 +122,6 @@ if (empty($objExercise)) {
$objExercise->read($exercise_id);
}
$feedback_type = $objExercise->feedback_type;
//Only users can see their own results
if (!$is_allowedToEdit) {
if ($student_id != $currentUserId) {
@ -293,11 +291,9 @@ if ($action == 'export') {
$user_info = api_get_user_info($student_id);
if ($show_results || $show_only_total_score || $showTotalScoreAndUserChoicesInLastAttempt) {
// Shows exercise header
echo $objExercise->show_exercise_result_header(
echo $objExercise->showExerciseResultHeader(
$user_info,
api_convert_and_format_date($exercise_date),
null,
$track_exercise_info['user_ip']
$track_exercise_info
);
}

@ -18,9 +18,8 @@ class HotpotatoesExerciseResult
/**
* Gets the results of all students (or just one student if access is limited).
*
* @param string The document path (for HotPotatoes retrieval)
* @param string $document_path The document path (for HotPotatoes retrieval)
* @param int User ID. Optional. If no user ID is provided, we take all the results. Defauts to null
* @param string $document_path
*
* @return bool
*/
@ -29,10 +28,7 @@ class HotpotatoesExerciseResult
$return = [];
$TBL_USER = Database::get_main_table(TABLE_MAIN_USER);
$TBL_TRACK_HOTPOTATOES = Database::get_main_table(TABLE_STATISTIC_TRACK_E_HOTPOTATOES);
$cid = api_get_course_id();
$course_id = api_get_course_int_id();
//$user_id = intval($user_id);
$user_id = null;
$session_id_and = ' AND te.session_id = '.api_get_session_id().' ';
$hotpotato_name = Database::escape_string($hotpotato_name);

@ -546,13 +546,7 @@ function lp_upload_quiz_action_handling()
if (!empty($lpObject)) {
$oLP = unserialize($lpObject);
if (is_object($oLP)) {
if ($debug > 0) {
error_log('New LP - oLP is object', 0);
}
if ((empty($oLP->cc)) || $oLP->cc != api_get_course_id()) {
if ($debug > 0) {
error_log('New LP - Course has changed, discard lp object', 0);
}
$oLP = null;
Session::erase('oLP');
Session::erase('lpobject');

@ -698,7 +698,6 @@ function store_forum($values, $courseInfo = [], $returnId = false)
}
// Forum images
$image_moved = false;
$has_attachment = false;
$image_moved = true;
if (!empty($_FILES['picture']['name'])) {
@ -5575,30 +5574,6 @@ function count_number_of_post_for_user_thread($thread_id, $user_id)
return $count;
}
/**
* This function counts the number of user register in course.
*
* @param int $course_id Course ID
*
* @deprecated use CourseManager::get_users_count_in_course
*
* @return int the number of user register in course
*
* @author Jhon Hinojosa <jhon.hinojosa@dokeos.com>,
*
* @version octubre 2008, dokeos 1.8
*/
function count_number_of_user_in_course($course_id)
{
$table = Database::get_main_table(TABLE_MAIN_COURSE_USER);
$sql = "SELECT * FROM $table
WHERE c_id ='".intval($course_id)."' ";
$result = Database::query($sql);
return count(Database::store_result($result));
}
/**
* This function retrieves information of statistical.
*

@ -25,8 +25,33 @@ $htmlHeadXtra[] = '<script>
function setFocus(){
$("#glossary_title").focus();
}
$(document).ready(function () {
setFocus();
$( "#dialog:ui-dialog" ).dialog( "destroy" );
$( "#dialog-confirm" ).dialog({
autoOpen: false,
show: "blind",
resizable: false,
height:300,
modal: true
});
$("#export_opener").click(function() {
var targetUrl = $(this).attr("href");
$( "#dialog-confirm" ).dialog({
width:400,
height:300,
buttons: {
"'.addslashes(get_lang('Download')).'": function() {
var export_format = $("input[name=export_format]:checked").val();
location.href = targetUrl+"&export_format="+export_format;
$( this ).dialog( "close" );
}
}
});
$( "#dialog-confirm" ).dialog("open");
return false;
});
});
</script>';
@ -225,11 +250,28 @@ switch ($action) {
'post',
api_get_self().'?action=import&'.api_get_cidreq()
);
$form->addHeader('header', get_lang('ImportGlossary'));
$form->addElement('file', 'file', get_lang('ImportCSVFileLocation'));
$form->addHeader(get_lang('ImportGlossary'));
$form->addElement('file', 'file', get_lang('File'));
$group = [];
$group[] = $form->createElement(
'radio',
'file_type',
'',
'CSV',
'csv'
);
$group[] = $form->createElement(
'radio',
'file_type',
'',
'XLS',
'xls'
);
$form->addGroup($group, '', get_lang('FileType'), null);
$form->addElement('checkbox', 'replace', null, get_lang('DeleteAllGlossaryTerms'));
$form->addElement('checkbox', 'update', null, get_lang('UpdateExistingGlossaryTerms'));
$form->addButtonImport(get_lang('Import'), 'SubmitImport');
$form->setDefaults(['file_type' => 'csv']);
$content = $form->returnForm();
$content .= get_lang('CSVMustLookLike').' ('.get_lang('MandatoryFields').')';
@ -240,6 +282,8 @@ switch ($action) {
</pre>';
if ($form->validate()) {
$values = $form->getSubmitValues();
$termsDeleted = [];
//this is a bad idea //jm
if (isset($_POST['replace']) && $_POST['replace']) {
@ -255,7 +299,17 @@ switch ($action) {
}
$updateTerms = isset($_POST['update']) && $_POST['update'] ? true : false;
$data = Import::csvToArray($_FILES['file']['tmp_name']);
$format = $values['file_type'];
switch ($format) {
case 'csv':
$data = Import::csvToArray($_FILES['file']['tmp_name']);
break;
case 'xls':
$data = Import::xlsToArray($_FILES['file']['tmp_name']);
break;
}
$goodList = [];
$updatedList = [];
$addedList = [];
@ -368,32 +422,8 @@ switch ($action) {
if (!api_is_allowed_to_edit(null, true)) {
api_not_allowed(true);
}
$data = GlossaryManager::get_glossary_data(
0,
GlossaryManager::get_number_glossary_terms(api_get_session_id()),
0,
'ASC'
);
usort($data, 'sorter');
$list = [];
$list[] = ['term', 'definition'];
$allowStrip = api_get_configuration_value('allow_remove_tags_in_glossary_export');
foreach ($data as $line) {
$definition = $line[1];
if ($allowStrip) {
$definition = strip_tags($definition);
}
$list[] = [$line[0], $definition];
}
$filename = 'glossary_course_'.api_get_course_id();
Export::arrayToCsv($list, $filename);
break;
case 'export_to_pdf':
if (!api_is_allowed_to_edit(null, true)) {
api_not_allowed(true);
}
GlossaryManager::export_to_pdf();
$format = isset($_GET['export_format']) ? $_GET['export_format'] : 'csv';
GlossaryManager::exportToFormat($format);
break;
case 'changeview':
if (in_array($_GET['view'], ['list', 'table'])) {
@ -429,4 +459,43 @@ Display::display_introduction_section(TOOL_GLOSSARY);
echo $content;
$extra = '<div id="dialog-confirm" title="'.get_lang("ConfirmYourChoice").'">';
$form = new FormValidator(
'report',
'post',
api_get_self().'?'.api_get_cidreq(),
null,
['class' => 'form-vertical']
);
$form->addElement(
'radio',
'export_format',
null,
get_lang('ExportAsCSV'),
'csv',
['id' => 'export_format_csv_label']
);
$form->addElement(
'radio',
'export_format',
null,
get_lang('ExportAsXLS'),
'xls',
['id' => 'export_format_xls_label']
);
$form->addElement(
'radio',
'export_format',
null,
get_lang('ExportToPDF'),
'pdf',
['id' => 'export_format_pdf_label']
);
$form->setDefaults(['export_format' => 'csv']);
$extra .= $form->returnForm();
$extra .= '</div>';
echo $extra;
Display::display_footer();

@ -29,7 +29,7 @@ $userList = CourseManager::get_user_list_from_course_code(
$sessionId,
null,
null,
$statusFilter
$statusToFilter
);
switch ($action) {

@ -666,7 +666,6 @@ if (isset($_GET['studentoverview'])) {
//if $category = 0 (which happens when GET['selectcat'] is undefined)
// then Category::load() will create a new 'root' category with empty
// course and session fields in memory (Category::create_root_category())
if ($_in_course === true) {
// When *inside* a course, we want to make sure there is one (and only
// one) category for this course or for this session.
@ -692,8 +691,8 @@ if (isset($_GET['studentoverview'])) {
// There is no category for this course+session, so create one
$cat = new Category();
if (!empty($session_id)) {
$s_name = api_get_session_name($session_id);
$cat->set_name($course_code.' - '.get_lang('Session').' '.$s_name);
$sessionName = api_get_session_name($session_id);
$cat->set_name($course_code.' - '.get_lang('Session').' '.$sessionName);
$cat->set_session_id($session_id);
} else {
$cat->set_name($course_code);
@ -895,6 +894,7 @@ if (isset($first_time) && $first_time == 1 && api_is_allowed_to_edit(null, true)
$i = 0;
$allcat = [];
/** @var Category $cat */
foreach ($cats as $cat) {
$allcat = $cat->get_subcategories($stud_id, $course_code, $session_id);
@ -934,13 +934,24 @@ if (isset($first_time) && $first_time == 1 && api_is_allowed_to_edit(null, true)
$exportToPdf = true;
}
$teacher = api_is_allowed_to_edit(null, true);
if ($teacher) {
$loadStats = false;
} else {
$loadStats = api_get_configuration_value('disable_gradebook_stats') === false;
}
$gradebookTable = new GradebookTable(
$cat,
$allcat,
$alleval,
$alllink,
$addparams,
$exportToPdf
$exportToPdf,
null,
null,
[],
$loadStats
);
$model = ExerciseLib::getCourseScoreModel();
@ -951,13 +962,23 @@ if (isset($first_time) && $first_time == 1 && api_is_allowed_to_edit(null, true)
];
} else {
if (empty($model)) {
$gradebookTable->td_attributes = [
3 => 'class="text-right"',
4 => 'class="text-center"',
5 => 'class="text-center"',
6 => 'class="text-center"',
7 => 'class="text-center"',
];
if ($loadStats) {
$gradebookTable->td_attributes = [
3 => 'class="text-right"',
4 => 'class="text-center"',
5 => 'class="text-center"',
6 => 'class="text-center"',
7 => 'class="text-center"',
];
} else {
$gradebookTable->td_attributes = [
3 => 'class="text-right"',
4 => 'class="text-center"',
5 => 'class="text-center"',
//6 => 'class="text-center"',
//7 => 'class="text-center"',
];
}
} else {
$gradebookTable->td_attributes = [
3 => 'class="text-right"',

@ -214,6 +214,10 @@ abstract class AbstractLink implements GradebookItem
public function getStudentList()
{
if (empty($this->studentList)) {
return [];
}
return $this->studentList;
}

@ -836,9 +836,9 @@ class Category implements GradebookItem
$name = $this->name;
$parent = $this->parent;
}
$tbl_grade_categories = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
$table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
$sql = "SELECT count(id) AS number
FROM $tbl_grade_categories
FROM $table
WHERE name = '".Database::escape_string($name)."'";
if (api_is_allowed_to_edit()) {
@ -864,7 +864,6 @@ class Category implements GradebookItem
} else {
$sql .= ' AND parent_id = '.intval($parent);
}
$result = Database::query($sql);
$number = Database::fetch_row($result);
@ -1509,6 +1508,7 @@ class Category implements GradebookItem
WHERE
cc.id = cu.c_id AND
cu.status = '.COURSEMANAGER;
if (!api_is_platform_admin()) {
$sql .= ' AND cu.user_id = '.$user_id;
}
@ -1690,17 +1690,6 @@ class Category implements GradebookItem
$session_id = null,
$order = null
) {
if (!empty($session_id)) {
/*$tbl_grade_categories = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
$sql = 'SELECT id FROM '.$tbl_grade_categories. ' WHERE session_id = '.$session_id;
$result_session = Database::query($sql);
if (Database::num_rows($result_session) > 0) {
$data_session = Database::fetch_array($result_session);
$parent_id = $data_session['id'];
return self::load(null, null, null, $parent_id, null, null, $order);
}*/
}
// 1 student
if (isset($studentId)) {
// Special case: this is the root

@ -25,6 +25,7 @@ class GradebookTable extends SortableTable
private $datagen;
private $evals_links;
private $dataForGraph;
private $loadStats = true;
/**
* GradebookTable constructor.
@ -48,7 +49,8 @@ class GradebookTable extends SortableTable
$exportToPdf = false,
$showTeacherView = null,
$userId = null,
$studentList = []
$studentList = [],
$loadStats = true
) {
$this->teacherView = is_null($showTeacherView) ? api_is_allowed_to_edit(null, true) : $showTeacherView;
$this->userId = is_null($userId) ? api_get_user_id() : $userId;
@ -67,6 +69,7 @@ class GradebookTable extends SortableTable
$this->evals_links = array_merge($evals, $links);
$this->currentcat = $currentcat;
$this->cats = $cats;
$this->loadStats = $loadStats;
$this->datagen = new GradebookDataGenerator($cats, $evals, $links);
if (!empty($userId)) {
@ -104,9 +107,13 @@ class GradebookTable extends SortableTable
$this->set_header($column++, get_lang('Weight'), false);
$this->set_header($column++, get_lang('Result'), false);
if (empty($model)) {
$this->set_header($column++, get_lang('Ranking'), false);
if ($this->loadStats) {
$this->set_header($column++, get_lang('Ranking'), false);
}
$this->set_header($column++, get_lang('BestScore'), false);
$this->set_header($column++, get_lang('Average'), false);
if ($this->loadStats) {
$this->set_header($column++, get_lang('Average'), false);
}
}
if (!empty($cats)) {
@ -214,13 +221,12 @@ class GradebookTable extends SortableTable
$course_code = api_get_course_id();
$session_id = api_get_session_id();
$statusToFilter = 0;
if (empty($session_id)) {
$statusToFilter = STUDENT;
} else {
$statusToFilter = 0;
}
if (empty($this->studentList)) {
if (empty($this->studentList) && $this->loadStats) {
$studentList = CourseManager::get_user_list_from_course_code(
$course_code,
$session_id,
@ -237,7 +243,8 @@ class GradebookTable extends SortableTable
$from,
$this->per_page,
false,
$this->studentList
$this->studentList,
$this->loadStats
);
// generate the data to display
@ -348,14 +355,13 @@ class GradebookTable extends SortableTable
}
} else {
$score = $item->calc_score($this->userId);
$scoreToDisplay = '-';
if (!empty($score[1])) {
$completeScore = $scoredisplay->display_score($score, SCORE_DIV_PERCENT);
$score = $score[0] / $score[1] * $item->get_weight();
$score = $scoredisplay->display_score([$score, null], SCORE_SIMPLE);
$scoreToDisplay = Display::tip($score, $completeScore);
} else {
$scoreToDisplay = '-';
$categoryScore = null;
}
@ -407,11 +413,17 @@ class GradebookTable extends SortableTable
if (empty($model)) {
// Ranking
$row[] = $ranking;
if ($this->loadStats) {
$row[] = $ranking;
}
// Best
$row[] = $best;
// Average
$row[] = $average;
if ($this->loadStats) {
$row[] = $average;
}
}
if (get_class($item) == 'Category') {
@ -454,7 +466,6 @@ class GradebookTable extends SortableTable
$sub_cat_info = new GradebookDataGenerator($allcat, $alleval, $alllink);
$sub_cat_info->userId = $user_id;
$data_array2 = $sub_cat_info->get_data(
$sorting,
$from,
@ -488,7 +499,7 @@ class GradebookTable extends SortableTable
$row[] = $this->build_type_column($item, ['style' => 'padding-left:5px']);
// Name.
$row[] = $invisibility_span_open."&nbsp;&nbsp;&nbsp; ".
$row[] = $invisibility_span_open."&nbsp;&nbsp;&nbsp; ".
$this->build_name_link($item, $type).$invisibility_span_close;
// Description.
@ -528,22 +539,24 @@ class GradebookTable extends SortableTable
if (count($eval_n_links) > 0) {
$value_data = isset($data[4]) ? $data[4] : null;
if (!is_null($value_data)) {
//$score = $item->calc_score(api_get_user_id());
//$new_score = $data[3] * $score[0] / $score[1];
//$new_score = floatval(number_format($new_score, api_get_setting('gradebook_number_decimals')));
// Result
$row[] = $value_data;
$best = isset($data['best']) ? $data['best'] : null;
$average = isset($data['average']) ? $data['average'] : null;
$ranking = isset($data['ranking']) ? $data['ranking'] : null;
// Ranking
$row[] = $ranking;
if ($this->loadStats) {
// Ranking
$row[] = $ranking;
}
// Best
$row[] = $best;
// Average
$row[] = $average;
if ($this->loadStats) {
$row[] = $average;
}
}
}
@ -709,16 +722,29 @@ class GradebookTable extends SortableTable
$totalAverage,
];
} else {
$row = [
null,
'<h3>'.get_lang('Total').'</h3>',
null,
$main_weight,
$totalResult,
$totalRanking,
$totalBest,
$totalAverage,
];
if ($this->loadStats) {
$row = [
null,
'<h3>'.get_lang('Total').'</h3>',
null,
$main_weight,
$totalResult,
$totalRanking,
$totalBest,
$totalAverage,
];
} else {
$row = [
null,
'<h3>'.get_lang('Total').'</h3>',
null,
$main_weight,
$totalResult,
//$totalRanking,
$totalBest,
//$totalAverage,
];
}
}
$sortable_data[] = $row;
@ -824,8 +850,10 @@ class GradebookTable extends SortableTable
SCORE_DIV_PERCENT_WITH_CUSTOM
);
$rowTotal[] = ' ';
$rowTotal[] = ' ';
$rowTotal[] = ' ';
if ($this->loadStats) {
$rowTotal[] = ' ';
$rowTotal[] = ' ';
}
$sortable_data[] = $rowTotal;
}

@ -90,7 +90,8 @@ class GradebookDataGenerator
$start = 0,
$count = null,
$ignore_score_color = false,
$studentList = []
$studentList = [],
$loadStats = true
) {
// do some checks on count, redefine if invalid value
if (!isset($count)) {
@ -107,7 +108,7 @@ class GradebookDataGenerator
// Get selected items
$visibleItems = array_slice($allitems, $start, $count);
$userCount = count($studentList);
$userCount = !empty($studentList) ? count($studentList) : 0;
// Generate the data to display
$data = [];
@ -154,6 +155,7 @@ class GradebookDataGenerator
$ranking = $this->buildRankingColumn($item, $userId, $userCount);
$row['ranking'] = $ranking['display'];
$row['ranking_score'] = $ranking['score'];
$row[] = $item;
}
} else {
@ -173,26 +175,29 @@ class GradebookDataGenerator
$row['best'] = $best['display'];
$row['best_score'] = $best['score'];
$rankingStudentList = [];
$invalidateResults = true;
// Average
$average = $this->buildAverageResultColumn($item);
$row['average'] = $average['display'];
$row['average_score'] = $average['score'];
// Ranking
$rankingStudentList = [];
$invalidateResults = true;
foreach ($studentList as $user) {
$score = $this->build_result_column(
$user['user_id'],
$item,
$ignore_score_color,
true
);
if (!empty($studentList)) {
foreach ($studentList as $user) {
$score = $this->build_result_column(
$user['user_id'],
$item,
$ignore_score_color,
true
);
if (!empty($score['score'][0])) {
$invalidateResults = false;
if (!empty($score['score'][0])) {
$invalidateResults = false;
}
$rankingStudentList[$user['user_id']] = $score['score'][0];
}
$rankingStudentList[$user['user_id']] = $score['score'][0];
}
$scoreDisplay = ScoreDisplay::instance();

@ -81,7 +81,8 @@ class GradeBookResult
*
* @param array $data
*
* @return bool|null False on error
* @throws PHPExcel_Exception
* @throws PHPExcel_Writer_Exception
*/
public function exportCompleteReportXLS($data)
{
@ -91,14 +92,14 @@ class GradeBookResult
$spreadsheet->setActiveSheetIndex(0);
$worksheet = $spreadsheet->getActiveSheet();
$line = 0;
$column = 1;
$line = 1;
$column = 0;
//headers
foreach ($data[0] as $header_col) {
$worksheet->SetCellValueByColumnAndRow(
$line,
$column,
$line,
html_entity_decode(strip_tags($header_col))
);
$column++;
@ -111,8 +112,8 @@ class GradeBookResult
$column = 0;
foreach ($data[1][$i] as $col_name) {
$worksheet->SetCellValueByColumnAndRow(
$line,
$column,
$line,
html_entity_decode(strip_tags($col_name))
);
$column++;

@ -0,0 +1,87 @@
<?php
/* For licensing terms, see /license.txt */
use Chamilo\SkillBundle\Entity\SkillRelItem;
require_once __DIR__.'/../inc/global.inc.php';
if (api_get_configuration_value('allow_skill_rel_items') == false) {
api_not_allowed(true);
}
api_protect_course_script();
GradebookUtils::block_students();
$courseId = api_get_course_int_id();
$sessionId = api_get_session_id();
$userId = isset($_GET['user_id']) ? (int) $_GET['user_id'] : 0;
$categoryId = isset($_GET['selectcat']) ? (int) $_GET['selectcat'] : 0;
$userInfo = api_get_user_info($userId);
if (empty($userInfo)) {
api_not_allowed(true);
}
$skills = Skill::getSkillRelItemsPerCourse($courseId, $sessionId);
$uniqueSkills = [];
$itemsPerSkill = [];
$uniqueSkillsConclusion = [];
$skillRelUser = new SkillRelUser();
$userSkills = $skillRelUser->getUserSkills($userId, api_get_course_int_id(), api_get_session_id());
$userSkillsList = [];
if (!empty($userSkills)) {
foreach ($userSkills as $userSkill) {
$userSkillsList[] = $userSkill['skill_id'];
}
}
$em = Database::getManager();
$codePath = api_get_path(WEB_CODE_PATH);
/** @var SkillRelItem $skill */
foreach ($skills as $skill) {
$skillId = $skill->getSkill()->getId();
$uniqueSkills[$skillId] = $skill->getSkill();
$itemInfo = Skill::getItemInfo($skill->getItemId(), $skill->getItemType());
$criteria = [
'user' => $userId,
'skillRelItem' => $skill,
];
/** @var \Chamilo\SkillBundle\Entity\SkillRelItemRelUser $skillRelItemRelUser */
$skillRelItemRelUser = $em->getRepository('ChamiloSkillBundle:SkillRelItemRelUser')->findOneBy($criteria);
$itemInfo['status'] = $skillRelItemRelUser ? true : false;
$itemInfo['url_activity'] = $codePath.$skill->getItemResultList(api_get_cidreq());
if ($skillRelItemRelUser) {
$itemInfo['url_activity'] = $codePath.$skillRelItemRelUser->getUserItemResultUrl(api_get_cidreq());
}
$itemsPerSkill[$skillId][]['info'] = $itemInfo;
}
foreach ($itemsPerSkill as $skillId => $skillList) {
$uniqueSkillsConclusion[$skillId] = in_array($skillId, $userSkillsList);
}
$interbreadcrumb[] = [
'url' => Category::getUrl(),
'name' => get_lang('Gradebook'),
];
$interbreadcrumb[] = [
'url' => api_get_path(WEB_CODE_PATH).'gradebook/gradebook_display_summary.php?'.api_get_cidreq().'&selectcat='.$categoryId,
'name' => get_lang('GradebookListOfStudentsReports'),
];
$url = api_get_path(WEB_AJAX_PATH).'skill.ajax.php?a=assign_user_to_skill';
$template = new Template(get_lang('SkillUserList'));
$template->assign('conclusion_list', $uniqueSkillsConclusion);
$template->assign('skills', $uniqueSkills);
$template->assign('items', $itemsPerSkill);
$template->assign('user', $userInfo);
$template->assign('course_id', api_get_course_int_id());
$template->assign('session_id', api_get_session_id());
$template->assign('assign_user_url', $url);
$templateName = $template->get_template('gradebook/skill_rel_user.tpl');
$content = $template->fetch($templateName);
$template->assign('content', $content);
$template->display_one_col_template();

@ -34,25 +34,21 @@ switch ($action) {
$list = explode(',', $_REQUEST['id']);
foreach ($list as $itemId) {
if (!api_is_session_general_coach() ||
api_is_element_in_the_session(TOOL_ANNOUNCEMENT, $itemId)
) {
if (!empty($groupId)) {
$result = AnnouncementManager::get_by_id(
api_get_course_int_id(),
$itemId
);
if (!empty($result)) {
$delete = true;
if (!empty($groupId) && $isTutor) {
if ($groupId != $result['to_group_id']) {
$delete = false;
}
}
if ($delete) {
AnnouncementManager::delete_announcement($courseInfo, $itemId);
if (!api_is_session_general_coach() || api_is_element_in_the_session(TOOL_ANNOUNCEMENT, $itemId)) {
$result = AnnouncementManager::get_by_id(
api_get_course_int_id(),
$itemId
);
if (!empty($result)) {
$delete = true;
if (!empty($groupId) && $isTutor) {
if ($groupId != $result['to_group_id']) {
$delete = false;
}
}
if ($delete) {
AnnouncementManager::delete_announcement($courseInfo, $itemId);
}
}
}
}

@ -118,6 +118,7 @@ switch ($action) {
get_lang('Uploaded')
);
} else {
$json['name'] = isset($file['name']) ? $file['name'] : get_lang('Unknown');
$json['url'] = '';
$json['error'] = get_lang('Error');
}

@ -536,8 +536,8 @@ switch ($action) {
exit;
}
$questionId = isset($_GET['question']) ? intval($_GET['question']) : 0;
$exerciseId = isset($_REQUEST['exercise']) ? intval($_REQUEST['exercise']) : 0;
$questionId = isset($_GET['question']) ? (int) $_GET['question'] : 0;
$exerciseId = isset($_REQUEST['exercise']) ? (int) $_REQUEST['exercise'] : 0;
if (!$questionId || !$exerciseId) {
break;
@ -547,9 +547,15 @@ switch ($action) {
$objExercise->read($exerciseId);
$objQuestion = Question::read($questionId);
$objQuestion->get_question_type_name();
echo '<p class="lead">'.$objQuestion->get_question_type_name().'</p>';
if ($objQuestion->type == FILL_IN_BLANKS) {
echo '<script>
$(function() {
$(".selectpicker").selectpicker({});
});
</script>';
}
ExerciseLib::showQuestion(
$objExercise,
$questionId,

@ -6,14 +6,26 @@ use Chamilo\CoreBundle\Entity\Tag;
require_once __DIR__.'/../global.inc.php';
$action = isset($_GET['a']) ? $_GET['a'] : '';
$type = isset($_REQUEST['type']) ? $_REQUEST['type'] : null;
$fieldId = isset($_REQUEST['field_id']) ? $_REQUEST['field_id'] : null;
switch ($action) {
case 'delete_file':
api_protect_admin_script();
$itemId = isset($_REQUEST['item_id']) ? $_REQUEST['item_id'] : null;
$extraFieldValue = new ExtraFieldValue($type);
$data = $extraFieldValue->get_values_by_handler_and_field_id($itemId, $fieldId);
if (!empty($data) && isset($data['id']) && !empty($data['value'])) {
$extraFieldValue->deleteValuesByHandlerAndFieldAndValue($itemId, $data['field_id'], $data['value']);
echo 1;
break;
}
echo 0;
break;
case 'get_second_select_options':
$type = isset($_REQUEST['type']) ? $_REQUEST['type'] : null;
$field_id = isset($_REQUEST['field_id']) ? $_REQUEST['field_id'] : null;
$option_value_id = isset($_REQUEST['option_value_id']) ? $_REQUEST['option_value_id'] : null;
if (!empty($type) && !empty($field_id) && !empty($option_value_id)) {
if (!empty($type) && !empty($fieldId) && !empty($option_value_id)) {
$field_options = new ExtraFieldOption($type);
echo $field_options->get_second_select_field_options_by_field(
$option_value_id,
@ -23,9 +35,6 @@ switch ($action) {
break;
case 'search_tags':
header('Content-Type: application/json');
$type = isset($_REQUEST['type']) ? $_REQUEST['type'] : null;
$fieldId = isset($_REQUEST['field_id']) ? $_REQUEST['field_id'] : null;
$tag = isset($_REQUEST['q']) ? $_REQUEST['q'] : null;
$result = [];

@ -8,12 +8,17 @@ use ChamiloSession as Session;
*/
require_once __DIR__.'/../global.inc.php';
api_protect_course_script(true);
$action = $_REQUEST['a'];
$debug = false;
$action = isset($_REQUEST['a']) ? $_REQUEST['a'] : '';
$course_id = api_get_course_int_id();
$tbl_lp_item = Database::get_course_table(TABLE_LP_ITEM);
$sessionId = api_get_session_id();
if ($debug) {
error_log('----------lp.ajax-------------- action '.$action);
}
switch ($action) {
case 'get_documents':
$courseInfo = api_get_course_info();
@ -102,6 +107,8 @@ switch ($action) {
}
}
$table = Database::get_course_table(TABLE_LP_ITEM);
foreach ($LP_item_list->list as $LP_item) {
$params = [];
$params['display_order'] = $LP_item->display_order;
@ -110,7 +117,7 @@ switch ($action) {
$params['parent_item_id'] = $LP_item->parent_item_id;
Database::update(
$tbl_lp_item,
$table,
$params,
[
'id = ? AND c_id = ? ' => [
@ -289,6 +296,23 @@ switch ($action) {
echo json_encode($position);
break;
case 'get_parent_names':
$newItemId = isset($_GET['new_item']) ? intval($_GET['new_item']) : 0;
if (!$newItemId) {
break;
}
/** @var \learnpath $lp */
$lp = Session::read('oLP');
$parentNames = $lp->getCurrentItemParentNames($newItemId);
$response = '';
foreach ($parentNames as $parentName) {
$response .= '<p class="h5 hidden-xs hidden-md">'.$parentName.'</p>';
}
echo $response;
break;
default:
echo '';

@ -1194,6 +1194,10 @@ switch ($action) {
$course = api_get_course_info();
// Used inside ExerciseLib::get_exam_results_data()
$documentPath = api_get_path(SYS_COURSE_PATH).$course['path']."/document";
$is_allowedToEdit = api_is_allowed_to_edit(null, true) ||
api_is_drh() ||
api_is_student_boss() ||
api_is_session_admin();
if ($is_allowedToEdit || api_is_student_boss()) {
$columns = [
'firstname',
@ -1316,7 +1320,8 @@ switch ($action) {
$courseInfo['code'],
true,
true,
$extraFieldsToAdd
$extraFieldsToAdd,
true
);
break;
case 'get_hotpotatoes_exercise_results':

@ -1,5 +1,6 @@
<?php
/* For licensing terms, see /license.txt */
/**
* Responses to AJAX calls.
*/
@ -20,12 +21,12 @@ switch ($action) {
case 'add':
if (api_is_platform_admin() || api_is_drh()) {
if (isset($_REQUEST['id']) && !empty($_REQUEST['id'])) {
$skill_id = $skill->edit($_REQUEST);
$skillId = $skill->edit($_REQUEST);
} else {
$skill_id = $skill->add($_REQUEST);
$skillId = $skill->add($_REQUEST);
}
}
echo $skill_id;
echo $skillId;
break;
case 'delete_skill':
if (api_is_platform_admin() || api_is_drh()) {
@ -73,10 +74,10 @@ switch ($action) {
echo json_encode($return);
break;
case 'get_course_info_popup':
$course_info = api_get_course_info($_REQUEST['code']);
$courseInfo = api_get_course_info($_REQUEST['code']);
$courses = CourseManager::processHotCourseItem(
[
['c_id' => $course_info['real_id']],
['c_id' => $courseInfo['real_id']],
]
);
Display::display_no_header();
@ -93,39 +94,39 @@ switch ($action) {
}
break;
case 'get_skills_by_profile':
$skill_rel_profile = new SkillRelProfile();
$skillRelProfile = new SkillRelProfile();
$profile_id = isset($_REQUEST['profile_id']) ? $_REQUEST['profile_id'] : null;
$skills = $skill_rel_profile->getSkillsByProfile($profile_id);
$skills = $skillRelProfile->getSkillsByProfile($profile_id);
echo json_encode($skills);
break;
case 'get_saved_profiles':
$skill_profile = new SkillProfile();
$profiles = $skill_profile->get_all();
$skillProfile = new SkillProfile();
$profiles = $skillProfile->get_all();
Display::display_no_header();
Display::$global_template->assign('profiles', $profiles);
$template = Display::$global_template->get_template('skill/profile_item.tpl');
echo Display::$global_template->fetch($template);
break;
case 'get_skills':
$load_user_data = isset($_REQUEST['load_user_data']) ? $_REQUEST['load_user_data'] : null;
$loadUserData = isset($_REQUEST['load_user_data']) ? $_REQUEST['load_user_data'] : null;
$id = intval($_REQUEST['id']);
$skills = $skill->get_all($load_user_data, false, $id);
$skills = $skill->get_all($loadUserData, false, $id);
echo json_encode($skills);
break;
case 'get_skill_info':
$id = isset($_REQUEST['id']) ? $_REQUEST['id'] : null;
$skill_info = $skill->getSkillInfo($id);
echo json_encode($skill_info);
$skillInfo = $skill->getSkillInfo($id);
echo json_encode($skillInfo);
break;
case 'get_skill_course_info':
$id = isset($_REQUEST['id']) ? $_REQUEST['id'] : null;
$skill_info = $skill->getSkillInfo($id);
$skillInfo = $skill->getSkillInfo($id);
$courses = $skill->getCoursesBySkill($id);
$sessions = $skill->getSessionsBySkill($id);
$html = '';
if (!empty($courses) || !empty($sessions)) {
Display::display_no_header();
Display::$global_template->assign('skill', $skill_info);
Display::$global_template->assign('skill', $skillInfo);
Display::$global_template->assign('courses', $courses);
Display::$global_template->assign('sessions', $sessions);
$template = Display::$global_template->get_template('skill/skill_info.tpl');
@ -218,7 +219,6 @@ switch ($action) {
$user_info = api_get_user_info($user['user_id']);
$user_list[$user['user_id']]['user'] = $user_info;
$my_user_skills = $skill_rel_user->getUserSkills($user['user_id']);
$user_skill_list = [];
foreach ($my_user_skills as $skill_item) {
$user_skill_list[] = $skill_item['skill_id'];
@ -349,14 +349,36 @@ switch ($action) {
]
);
$returnSkills = [];
foreach ($skills as $skill) {
$returnSkills[] = [
'id' => $skill['id'],
'text' => $skill['name'],
];
}
echo json_encode([
'items' => $returnSkills,
]);
break;
case 'search_skills_in_course':
$courseId = isset($_REQUEST['course_id']) ? (int) $_REQUEST['course_id'] : 0;
$sessionId = isset($_REQUEST['session_id']) ? (int) $_REQUEST['session_id'] : null;
if (empty($courseId)) {
exit;
}
$em = Database::getManager();
$skills = $em->getRepository('ChamiloSkillBundle:SkillRelCourse')->findBy(
['course' => $courseId, 'session' => $sessionId]
);
$returnSkills = [];
/** @var \Chamilo\SkillBundle\Entity\SkillRelCourse $skill */
foreach ($skills as $skill) {
$returnSkills[] = [
'id' => $skill->getSkill()->getId(),
'text' => $skill->getSkill()->getName(),
];
}
echo json_encode([
'items' => $returnSkills,
]);
@ -378,6 +400,7 @@ switch ($action) {
$userId = isset($_REQUEST['user_id']) ? (int) $_REQUEST['user_id'] : 0;
$courseId = isset($_REQUEST['course_id']) ? (int) $_REQUEST['course_id'] : 0;
$sessionId = isset($_REQUEST['session_id']) ? (int) $_REQUEST['session_id'] : 0;
$resultId = isset($_REQUEST['result_id']) ? (int) $_REQUEST['result_id'] : 0;
if (!empty($typeId) && !empty($itemId) && !empty($skillId) && !empty($userId) && !empty($courseId)) {
$em = Database::getManager();
@ -392,7 +415,6 @@ switch ($action) {
}
$session = $em->getRepository('ChamiloCoreBundle:Session')->find($sessionId);
/** @var \Chamilo\SkillBundle\Entity\SkillRelItem $skillRelItem */
$skillRelItem = $em->getRepository('ChamiloSkillBundle:SkillRelItem')->findOneBy(
['itemId' => $itemId, 'itemType' => $typeId, 'skill' => $skillId]
@ -413,6 +435,7 @@ switch ($action) {
$skillRelItemRelUser
->setUser($user)
->setSkillRelItem($skillRelItem)
->setResultId($resultId)
->setCreatedBy($creatorId)
->setUpdatedBy($creatorId)
;
@ -423,6 +446,72 @@ switch ($action) {
echo Skill::getUserSkillStatusLabel($skillRelItem, $skillRelItemRelUser, false);
}
break;
case 'assign_user_to_skill':
$allowSkillInTools = api_get_configuration_value('allow_skill_rel_items');
if (empty($allowSkillInTools)) {
exit;
}
if (!api_is_allowed_to_edit()) {
exit;
}
$skillId = isset($_REQUEST['skill_id']) ? (int) $_REQUEST['skill_id'] : 0;
$userId = isset($_REQUEST['user_id']) ? (int) $_REQUEST['user_id'] : 0;
$courseId = isset($_REQUEST['course_id']) ? (int) $_REQUEST['course_id'] : 0;
$sessionId = isset($_REQUEST['session_id']) ? (int) $_REQUEST['session_id'] : null;
if (empty($skillId) || empty($userId)) {
exit;
}
$em = Database::getManager();
$skillRepo = $em->getRepository('ChamiloCoreBundle:Skill');
$skill = $skillRepo->find($skillId);
$user = api_get_user_entity($userId);
if (empty($skill) || empty($user)) {
exit;
}
$skillUserRepo = $em->getRepository('ChamiloCoreBundle:SkillRelUser');
$criteria = [
'user' => $user,
'skill' => $skill,
];
$skillRelUsers = $skillUserRepo->findBy($criteria);
if (empty($skillRelUsers)) {
$skillUser = new \Chamilo\CoreBundle\Entity\SkillRelUser();
$skillUser->setUser($user);
$skillUser->setSkill($skill);
/*if ($showLevels) {
$level = $skillLevelRepo->find(intval($values['acquired_level']));
$skillUser->setAcquiredLevel($level);
}*/
$course = api_get_course_entity($courseId);
$skillUser->setCourse($course);
if (!empty($sessionId)) {
$session = $em->getRepository('ChamiloCoreBundle:Session')->find($sessionId);
$skillUser->setSession($session);
}
$skillUser->setArgumentation('');
$skillUser->setArgumentationAuthorId(api_get_user_id());
$skillUser->setAcquiredSkillAt(new DateTime());
$skillUser->setAssignedBy(0);
$em->persist($skillUser);
$em->flush();
$result = 'success';
} else {
foreach ($skillRelUsers as $skillRelUser) {
$em->remove($skillRelUser);
}
$em->flush();
$result = 'danger';
}
echo $result;
break;
default:
echo '';
}

@ -36,8 +36,8 @@ class aiccItem extends learnpathItem
* Class constructor. Depending of the type of construction called ('db' or 'manifest'), will create a scormItem
* object from database records or from the array given as second parameter.
*
* @param string Type of construction needed ('db' or 'config', default = 'config')
* @param mixed Depending on the type given, DB id for the lp_item or parameters array
* @param string Type of construction needed ('db' or 'config', default = 'config')
* @param mixed Depending on the type given, DB id for the lp_item or parameters array
*/
public function __construct($type = 'config', $params = [], $course_id = null)
{
@ -50,7 +50,6 @@ class aiccItem extends learnpathItem
// no break
case 'config': // Do the same as the default.
default:
//if($first_item->type == XML_ELEMENT_NODE) this is already check prior to the call to this function
foreach ($params as $a => $value) {
switch ($a) {
case 'system_id':
@ -109,10 +108,10 @@ class aiccItem extends learnpathItem
/**
* Builds a flat list with the current item and calls itself recursively on all children.
*
* @param array Reference to the array to complete with the current item
* @param int Optional absolute order (pointer) of the item in this learning path
* @param int Optional relative order of the item at this level
* @param int Optional level. If not given, assumes it's level 0
* @param array Reference to the array to complete with the current item
* @param int Optional absolute order (pointer) of the item in this learning path
* @param int Optional relative order of the item at this level
* @param int Optional level. If not given, assumes it's level 0
*/
public function get_flat_list(&$list, &$abs_order, $rel_order = 1, $level = 0)
{
@ -141,7 +140,7 @@ class aiccItem extends learnpathItem
/**
* Save function. Uses the parent save function and adds a layer for AICC.
*
* @param bool Save from URL params (1) or from object attributes (0)
* @param bool Save from URL params (1) or from object attributes (0)
*/
public function save($from_outside = true, $prereqs_complete = false)
{

@ -269,6 +269,7 @@ if (!empty($_REQUEST['command'])) {
}
Session::write('lpobject', serialize($oLP));
Session::write('oLP', $oLP);
session_write_close();
// Content type must be text/plain.
header('Content-type: text/plain');

File diff suppressed because it is too large Load Diff

@ -236,20 +236,6 @@ class learnpathItem
if (($index + 1) > $this->interactions_count) {
$this->interactions_count = $index + 1;
}
/*
if (is_array($this->interactions[$index]) && count($this->interactions[$index]) > 0) {
$this->interactions[$index] = $params;
return false;
} else {
if (count($params)==8) {
// We rely on the calling script to provide parameters in the right order.
$this->interactions[$index] = $params;
return true;
} else {
return false;
}
}
*/
}
/**
@ -312,7 +298,6 @@ class learnpathItem
}
$lp_item_view = Database::get_course_table(TABLE_LP_ITEM_VIEW);
$lp_item = Database::get_course_table(TABLE_LP_ITEM);
$course_id = api_get_course_int_id();
$sql = "DELETE FROM $lp_item_view
@ -768,10 +753,10 @@ class learnpathItem
public function get_lesson_mode()
{
$mode = 'normal';
if ($this->get_prevent_reinit() != 0) { // If prevent_reinit == 0
if ($this->get_prevent_reinit() != 0) {
// If prevent_reinit == 0
$my_status = $this->get_status();
if ($my_status != $this->possible_status[0]
&& $my_status != $this->possible_status[1]) {
if ($my_status != $this->possible_status[0] && $my_status != $this->possible_status[1]) {
$mode = 'review';
}
}
@ -1793,9 +1778,8 @@ class learnpathItem
*/
public function get_terms()
{
$lp_item = Database::get_course_table(TABLE_LP_ITEM);
$course_id = api_get_course_int_id();
$sql = "SELECT * FROM $lp_item
$table = Database::get_course_table(TABLE_LP_ITEM);
$sql = "SELECT * FROM $table
WHERE iid = ".intval($this->db_id);
$res = Database::query($sql);
$row = Database::fetch_array($res);
@ -1827,7 +1811,8 @@ class learnpathItem
*/
public function get_total_time()
{
if (self::DEBUG > 0) {
$debug = self::DEBUG;
if ($debug) {
error_log(
'learnpathItem::get_total_time() for item '.$this->db_id.
' - Initially, current_start_time = '.$this->current_start_time.
@ -1837,7 +1822,7 @@ class learnpathItem
}
if ($this->current_start_time == 0) {
// Shouldn't be necessary thanks to the open() method.
if (self::DEBUG > 2) {
if ($debug) {
error_log(
'learnpathItem::get_total_time() - Current start time was empty',
0
@ -1849,7 +1834,7 @@ class learnpathItem
if (time() < $this->current_stop_time ||
$this->current_stop_time == 0
) {
if (self::DEBUG > 2) {
if ($debug) {
error_log(
'learnpathItem::get_total_time() - Current stop time was '
.'greater than the current time or was empty',
@ -1865,7 +1850,7 @@ class learnpathItem
$time = $this->current_stop_time - $this->current_start_time;
if ($time < 0) {
if (self::DEBUG > 2) {
if ($debug) {
error_log(
'learnpathItem::get_total_time() - Time smaller than 0. Returning 0',
0
@ -1875,7 +1860,7 @@ class learnpathItem
return 0;
} else {
$time = $this->fixAbusiveTime($time);
if (self::DEBUG > 2) {
if ($debug) {
error_log(
'Current start time = '.$this->current_start_time.', current stop time = '.
$this->current_stop_time.' Returning '.$time."-----------\n"
@ -2030,6 +2015,8 @@ class learnpathItem
/**
* Opens/launches the item. Initialises runtime values.
*
* @param bool $allow_new_attempt
*
* @return bool true on success, false on failure
*/
public function open($allow_new_attempt = false)
@ -2505,7 +2492,9 @@ class learnpathItem
if (isset($minScore) && isset($minScore)) {
// Taking min/max prerequisites values see BT#5776
if ($quiz['exe_result'] >= $minScore && $quiz['exe_result'] <= $maxScore) {
if ($quiz['exe_result'] >= $minScore &&
$quiz['exe_result'] <= $maxScore
) {
$returnstatus = true;
} else {
$this->prereq_alert = get_lang('LearnpathPrereqNotCompleted');
@ -2513,7 +2502,9 @@ class learnpathItem
}
} else {
// Classic way
if ($quiz['exe_result'] >= $items[$refs_list[$prereqs_string]]->get_mastery_score()) {
if ($quiz['exe_result'] >=
$items[$refs_list[$prereqs_string]]->get_mastery_score()
) {
$returnstatus = true;
} else {
$this->prereq_alert = get_lang('LearnpathPrereqNotCompleted');
@ -2577,7 +2568,6 @@ class learnpathItem
} else {
$status = $items[$refs_list[$prereqs_string]]->get_status(false);
$returnstatus = $status == $this->possible_status[2] || $status == $this->possible_status[3];
if (!$returnstatus) {
if (self::DEBUG > 1) {
error_log(
@ -2623,9 +2613,7 @@ class learnpathItem
lp_item_id = '.$refs_list[$prereqs_string].'
LIMIT 0, 1';
$rs_lp = Database::query($sql);
$status_array = Database::fetch_row(
$rs_lp
);
$status_array = Database::fetch_row($rs_lp);
$status = $status_array[0];
$returnstatus = ($status == $this->possible_status[2]) || ($status == $this->possible_status[3]);
@ -2791,8 +2779,6 @@ class learnpathItem
//$this->current_score = 0;
$this->current_start_time = 0;
$this->current_stop_time = 0;
//$this->current_data = '';scorm
//$this->status = $this->possible_status[0];
$this->interactions_count = $this->get_interactions_count(true);
}
@ -2810,7 +2796,8 @@ class learnpathItem
*/
public function save($from_outside = true, $prereqs_complete = false)
{
if (self::DEBUG > 0) {
$debug = self::DEBUG;
if ($debug) {
error_log('learnpathItem::save()', 0);
}
// First check if parameters passed via GET can be saved here
@ -2821,7 +2808,7 @@ class learnpathItem
$status != $this->possible_status[0] && // not attempted
$status != $this->possible_status[1] //incomplete
) {
if (self::DEBUG > 1) {
if ($debug) {
error_log(
'learnpathItem::save() - save reinit blocked by setting',
0
@ -2830,7 +2817,7 @@ class learnpathItem
// Do nothing because the status has already been set. Don't allow it to change.
// TODO: Check there isn't a special circumstance where this should be saved.
} else {
if (self::DEBUG > 1) {
if ($debug) {
error_log(
'learnpathItem::save() - SCORM save request received',
0
@ -2839,7 +2826,7 @@ class learnpathItem
// Get all new settings from the URL
if ($from_outside) {
if (self::DEBUG > 1) {
if ($debug) {
error_log(
'learnpathItem::save() - Getting item data from outside',
0
@ -2849,7 +2836,7 @@ class learnpathItem
switch ($param) {
case 'score':
$this->set_score($value);
if (self::DEBUG > 2) {
if ($debug) {
error_log(
'learnpathItem::save() - setting score to '.$value,
0
@ -2858,7 +2845,7 @@ class learnpathItem
break;
case 'max':
$this->set_max_score($value);
if (self::DEBUG > 2) {
if ($debug) {
error_log(
'learnpathItem::save() - setting view_max_score to '.$value,
0
@ -2867,7 +2854,7 @@ class learnpathItem
break;
case 'min':
$this->min_score = $value;
if (self::DEBUG > 2) {
if ($debug) {
error_log(
'learnpathItem::save() - setting min_score to '.$value,
0
@ -2877,7 +2864,7 @@ class learnpathItem
case 'lesson_status':
if (!empty($value)) {
$this->set_status($value);
if (self::DEBUG > 2) {
if ($debug) {
error_log(
'learnpathItem::save() - setting status to '.$value,
0
@ -2887,7 +2874,7 @@ class learnpathItem
break;
case 'time':
$this->set_time($value);
if (self::DEBUG > 2) {
if ($debug) {
error_log(
'learnpathItem::save() - setting time to '.$value,
0
@ -2896,7 +2883,7 @@ class learnpathItem
break;
case 'suspend_data':
$this->current_data = $value;
if (self::DEBUG > 2) {
if ($debug) {
error_log(
'learnpathItem::save() - setting suspend_data to '.$value,
0
@ -2905,7 +2892,7 @@ class learnpathItem
break;
case 'lesson_location':
$this->set_lesson_location($value);
if (self::DEBUG > 2) {
if ($debug) {
error_log(
'learnpathItem::save() - setting lesson_location to '.$value,
0
@ -2914,7 +2901,7 @@ class learnpathItem
break;
case 'core_exit':
$this->set_core_exit($value);
if (self::DEBUG > 2) {
if ($debug) {
error_log(
'learnpathItem::save() - setting core_exit to '.$value,
0
@ -2922,28 +2909,16 @@ class learnpathItem
}
break;
case 'interactions':
//$interactions = unserialize($value);
//foreach($interactions as $interaction){
// ;
//}
break;
case 'objectives':
break;
//case 'maxtimeallowed':
//$this->set_max_time_allowed($value);
//break;
/*
case 'objectives._count':
$this->attempt_id = $value;
break;
*/
default:
// Ignore.
break;
}
}
} else {
if (self::DEBUG > 1) {
if ($debug) {
error_log(
'learnpathItem::save() - Using inside item status',
0
@ -2955,6 +2930,9 @@ class learnpathItem
} else {
// If not SCO, such messages should not be expected.
$type = strtolower($this->type);
if ($debug) {
error_log("type: $type");
}
switch ($type) {
case 'asset':
if ($prereqs_complete) {
@ -2976,7 +2954,7 @@ class learnpathItem
}
}
if (self::DEBUG > 1) {
if ($debug) {
error_log(
'New LP - End of learnpathItem::save() - Calling write_to_db()',
0
@ -3364,7 +3342,6 @@ class learnpathItem
public function set_terms($terms)
{
global $charset;
$course_id = api_get_course_int_id();
$lp_item = Database::get_course_table(TABLE_LP_ITEM);
$a_terms = preg_split('/,/', $terms);
$i_terms = preg_split('/,/', $this->get_terms());
@ -3406,27 +3383,26 @@ class learnpathItem
* often give it as 00:00:00.0000.
*
* @param string Time as given by SCORM
* @param string $format
*/
public function set_time($scorm_time, $format = 'scorm')
{
$debug = self::DEBUG;
if ($debug > 0) {
error_log('learnpathItem::set_time('.$scorm_time.')', 0);
if ($debug) {
error_log("learnpathItem::set_time($scorm_time, $format)");
error_log("this->type: ".$this->type);
error_log("this->current_start_time: ".$this->current_start_time);
}
if ($scorm_time == '0' &&
$this->type != 'sco' &&
$this->current_start_time != 0
) {
$my_time = time() - $this->current_start_time;
if ($my_time > 0) {
$this->update_time($my_time);
if ($debug > 0) {
error_log(
'learnpathItem::set_time('.$scorm_time.') - '.
'found asset - set time to '.$my_time,
0
);
$myTime = time() - $this->current_start_time;
if ($myTime > 0) {
$this->update_time($myTime);
if ($debug) {
error_log('found asset - set time to '.$myTime);
}
}
} else {
@ -3443,11 +3419,11 @@ class learnpathItem
$min = $res[2];
$sec = $res[3];
// Getting total number of seconds spent.
$total_sec = $hour * 3600 + $min * 60 + $sec;
if ($debug > 0) {
error_log("total_sec : $total_sec");
$totalSec = $hour * 3600 + $min * 60 + $sec;
if ($debug) {
error_log("totalSec : $totalSec");
}
$this->scorm_update_time($total_sec);
$this->scorm_update_time($totalSec);
}
break;
case 'int':
@ -3540,42 +3516,20 @@ class learnpathItem
/**
* Updates the time info according to the given session_time.
*
* @param int $total_sec Time in seconds
* @param int $totalSec Time in seconds
*/
public function update_time($total_sec = 0)
public function update_time($totalSec = 0)
{
if (self::DEBUG > 0) {
error_log('learnpathItem::update_time('.$total_sec.')', 0);
error_log('learnpathItem::update_time('.$totalSec.')');
}
if ($total_sec >= 0) {
if ($totalSec >= 0) {
// Getting start time from finish time. The only problem in the calculation is it might be
// modified by the scripts processing time.
$now = time();
$start = $now - $total_sec;
$start = $now - $totalSec;
$this->current_start_time = $start;
$this->current_stop_time = $now;
/*if (empty($this->current_start_time)) {
$this->current_start_time = $start;
$this->current_stop_time = $now;
} else {
//if ($this->current_stop_time != $this->current_start_time) {
// If the stop time has already been set before to something else
// than the start time, add the given time to what's already been
// recorder.
// This is the SCORM way of doing things, because the time comes from
// core.session_time, not core.total_time
// UPDATE: adding time to previous time is only done on SCORM's finish()
// call, not normally, so for now ignore this section.
//$this->current_stop_time = $this->current_stop_time + $stop;
//error_log('New LP - Adding '.$stop.' seconds - now '.$this->current_stop_time, 0);
//} else {
// If no previous stop time set, use the one just calculated now from
// start time.
//$this->current_start_time = $start;
//$this->current_stop_time = $now;
//error_log('New LP - Setting '.$stop.' seconds - now '.$this->current_stop_time, 0);
//}
}*/
}
}
@ -3588,7 +3542,7 @@ class learnpathItem
public function scorm_update_time($total_sec = 0)
{
$debug = self::DEBUG;
if ($debug > 0) {
if ($debug) {
error_log('learnpathItem::scorm_update_time()');
error_log("total_sec: $total_sec");
}
@ -3612,7 +3566,7 @@ class learnpathItem
} else {
$total_time = $row['total_time'];
}
if ($debug > 0) {
if ($debug) {
error_log("Original total_time: $total_time");
}
@ -3627,13 +3581,15 @@ class learnpathItem
}
// Step 2.1 : if normal mode total_time = total_time + total_sec
if ($accumulateScormTime != 0) {
if ($this->type == 'sco' && $accumulateScormTime != 0) {
if ($debug) {
error_log("accumulateScormTime is on. total_time modified: $total_time + $total_sec");
}
$total_time += $total_sec;
} else {
// Step 2.2 : if not cumulative mode total_time = total_time - last_update + total_sec
$total_sec = $this->fixAbusiveTime($total_sec);
if ($debug > 0) {
if ($debug) {
error_log("after fix abusive: $total_sec");
error_log("total_time: $total_time");
error_log("this->last_scorm_session_time: ".$this->last_scorm_session_time);
@ -3647,7 +3603,7 @@ class learnpathItem
}
}
if ($debug > 0) {
if ($debug) {
error_log("accumulate_scorm_time: $accumulateScormTime");
error_log("total_time modified: $total_time");
}
@ -3671,8 +3627,10 @@ class learnpathItem
lp_item_id = {$this->db_id} AND
lp_view_id = {$this->view_id} AND
view_count = {$this->get_attempt_id()}";
if ($debug > 0) {
if ($debug) {
error_log('-------------total_time updated ------------------------');
error_log($sql);
error_log('-------------------------------------');
}
Database::query($sql);
}
@ -3786,13 +3744,14 @@ class learnpathItem
*/
public function write_to_db()
{
if (self::DEBUG > 0) {
$debug = self::DEBUG;
if ($debug) {
error_log('learnpathItem::write_to_db()', 0);
}
// Check the session visibility.
if (!api_is_allowed_to_session_edit()) {
if (self::DEBUG > 0) {
if ($debug) {
error_log('return false api_is_allowed_to_session_edit');
}
@ -3836,13 +3795,13 @@ class learnpathItem
($this->type == 'sco' && ($credit == 'no-credit' || $mode == 'review' || $mode == 'browse'))) &&
($this->seriousgame_mode != 1 && $this->type == 'sco')
) {
if (self::DEBUG > 1) {
if ($debug) {
error_log(
"This info shouldn't be saved as the credit or lesson mode info prevent it"
);
error_log(
'learnpathItem::write_to_db() - credit('.$credit.') or'.
' lesson_mode('.$mode.') prevent recording!',
' lesson_mode('.$mode.') prevent recording!',
0
);
}
@ -3870,7 +3829,7 @@ class learnpathItem
//"max_time_allowed" => ,
"lesson_location" => $this->lesson_location,
];
if (self::DEBUG > 2) {
if ($debug) {
error_log(
'learnpathItem::write_to_db() - Inserting into item_view forced: '.print_r($params, 1),
0
@ -3892,7 +3851,7 @@ class learnpathItem
lp_item_id = ".$this->db_id." AND
lp_view_id = ".$this->view_id." AND
view_count = ".intval($this->get_attempt_id());
if (self::DEBUG > 2) {
if ($debug) {
error_log(
'learnpathItem::write_to_db() - Querying item_view: '.$sql,
0
@ -3917,7 +3876,7 @@ class learnpathItem
"lesson_location" => $this->lesson_location,
];
if (self::DEBUG > 2) {
if ($debug) {
error_log(
'learnpathItem::write_to_db() - Inserting into item_view forced: '.print_r($params, 1),
0
@ -3953,27 +3912,27 @@ class learnpathItem
} else {
// For all other content types...
if ($this->type == 'quiz') {
if ($debug) {
error_log("item is quiz:");
}
$my_status = ' ';
$total_time = ' ';
if (!empty($_REQUEST['exeId'])) {
$table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
$safe_exe_id = intval($_REQUEST['exeId']);
$sql = "SELECT start_date, exe_date
$exeId = (int) $_REQUEST['exeId'];
$sql = "SELECT exe_duration
FROM $table
WHERE exe_id = $safe_exe_id";
WHERE exe_id = $exeId";
if ($debug) {
error_log($sql);
}
$res = Database::query($sql);
$row_dates = Database::fetch_array($res);
$time_start_date = convert_sql_date(
$row_dates['start_date']
);
$time_exe_date = convert_sql_date(
$row_dates['exe_date']
);
$mytime = ((int) $time_exe_date - (int) $time_start_date);
$mytime = $this->fixAbusiveTime($mytime);
$total_time = " total_time = ".$mytime.", ";
$exeRow = Database::fetch_array($res);
$duration = $exeRow['exe_duration'];
$total_time = " total_time = ".$duration.", ";
if ($debug) {
error_log("quiz: $total_time");
}
}
} else {
$my_type_lp = learnpath::get_type_static($this->lp_id);
@ -3989,6 +3948,9 @@ class learnpathItem
if ($this->seriousgame_mode == 1 && $this->type == 'sco') {
$total_time = " total_time = total_time +".$this->get_total_time().", ";
$my_status = " status = '".$this->get_status(false)."' ,";
if ($debug) {
error_log("seriousgame_mode time changed: $total_time");
}
} elseif ($this->get_prevent_reinit() == 1) {
// Process of status verified into data base.
$sql = 'SELECT status FROM '.$item_view_table.'
@ -4008,6 +3970,9 @@ class learnpathItem
) {
$total_time = " total_time = total_time +".$this->get_total_time().", ";
$my_status = " status = '".$this->get_status(false)."' ,";
if ($debug) {
error_log("get_prevent_reinit = 1 time changed: $total_time");
}
} else {
// Verified into database.
if (!in_array($row_verified['status'], $case_completed) &&
@ -4015,17 +3980,26 @@ class learnpathItem
) {
$total_time = " total_time = total_time +".$this->get_total_time().", ";
$my_status = " status = '".$this->get_status(false)."' ,";
if ($debug) {
error_log("total_time time changed case 1: $total_time");
}
} elseif (in_array($row_verified['status'], $case_completed) &&
$my_type_lp == 2 && $this->type != 'sco'
) {
$total_time = " total_time = total_time +".$this->get_total_time().", ";
$my_status = " status = '".$this->get_status(false)."' ,";
if ($debug) {
error_log("total_time time changed case 2: $total_time");
}
} else {
if (($my_type_lp == 3 && $this->type == 'au') ||
($my_type_lp == 1 && $this->type != 'dir')) {
// Is AICC or Chamilo LP
$total_time = " total_time = total_time + ".$this->get_total_time().", ";
$my_status = " status = '".$this->get_status(false)."' ,";
if ($debug) {
error_log("total_time time changed case 3: $total_time");
}
}
}
}
@ -4034,13 +4008,22 @@ class learnpathItem
if (in_array($this->get_status(false), $case_completed) && $my_type_lp == 2) {
// Reset zero new attempt ?
$my_status = " status = '".$this->get_status(false)."' ,";
if ($debug) {
error_log("total_time time changed Multiple attempt case 1: $total_time");
}
} elseif (!in_array($this->get_status(false), $case_completed) && $my_type_lp == 2) {
$total_time = " total_time = ".$this->get_total_time().", ";
$my_status = " status = '".$this->get_status(false)."' ,";
if ($debug) {
error_log("total_time time changed Multiple attempt case 2: $total_time");
}
} else {
// It is chamilo LP.
$total_time = " total_time = total_time +".$this->get_total_time().", ";
$my_status = " status = '".$this->get_status(false)."' ,";
if ($debug) {
error_log("total_time time changed Multiple attempt case 3: $total_time");
}
}
// This code line fixes the problem of wrong status.
@ -4064,6 +4047,10 @@ class learnpathItem
} else {
$total_time = " total_time = total_time + ".$this->get_total_time().", ";
}
if ($debug) {
error_log("total_time time my_type_lp: $total_time");
}
}
}
}
@ -4101,11 +4088,11 @@ class learnpathItem
}
$this->current_start_time = time();
}
if (self::DEBUG > 2) {
error_log(
'learnpathItem::write_to_db() - Updating item_view: '.$sql,
0
);
if ($debug) {
error_log('-------------------------------------------');
error_log('learnpathItem::write_to_db() - Updating item_view:');
error_log($sql);
error_log('-------------------------------------------');
}
Database::query($sql);
}
@ -4125,10 +4112,10 @@ class learnpathItem
if (Database::num_rows($res) > 0) {
$row = Database::fetch_array($res);
$lp_iv_id = $row[0];
if (self::DEBUG > 2) {
if ($debug) {
error_log(
'learnpathItem::write_to_db() - Got item_view_id '.
$lp_iv_id.', now checking interactions ',
$lp_iv_id.', now checking interactions ',
0
);
}
@ -4223,7 +4210,7 @@ class learnpathItem
}
}
if (self::DEBUG > 2) {
if ($debug) {
error_log('End of learnpathItem::write_to_db()', 0);
}
@ -4323,11 +4310,12 @@ class learnpathItem
$course_info['code']
);
$file_path = '';
if (!empty($document_data)) {
$file_path = basename($document_data['path']);
// Store the mp3 file in the lp_item table.
$tbl_lp_item = Database::get_course_table(TABLE_LP_ITEM);
$sql = "UPDATE $tbl_lp_item SET
$table = Database::get_course_table(TABLE_LP_ITEM);
$sql = "UPDATE $table SET
audio = '".Database::escape_string($file_path)."'
WHERE iid = ".intval($this->db_id);
Database::query($sql);
@ -4345,12 +4333,11 @@ class learnpathItem
*/
public function remove_audio()
{
$tbl_lp_item = Database::get_course_table(TABLE_LP_ITEM);
$course_id = api_get_course_int_id();
if (empty($this->db_id)) {
return false;
}
$sql = "UPDATE $tbl_lp_item SET
$table = Database::get_course_table(TABLE_LP_ITEM);
$sql = "UPDATE $table SET
audio = ''
WHERE iid IN (".$this->db_id.")";
Database::query($sql);
@ -4556,7 +4543,7 @@ class learnpathItem
*/
public function createForumThread($currentForumId)
{
require_once api_get_path(SYS_CODE_PATH).'/forum/forumfunction.inc.php';
require_once api_get_path(SYS_CODE_PATH).'forum/forumfunction.inc.php';
$em = Database::getManager();
$threadRepo = $em->getRepository('ChamiloCourseBundle:CForumThread');
@ -4605,7 +4592,7 @@ class learnpathItem
*/
public function dissociateForumThread($threadIid)
{
$threadIid = intval($threadIid);
$threadIid = (int) $threadIid;
$em = Database::getManager();
$forumThread = $em->find('ChamiloCourseBundle:CForumThread', $threadIid);
@ -4614,9 +4601,7 @@ class learnpathItem
return false;
}
$forumThread->setThreadTitle(
"{$this->get_title()} - {$this->db_id}"
);
$forumThread->setThreadTitle("{$this->get_title()} - {$this->db_id}");
$forumThread->setLpItemId(0);
$em->persist($forumThread);
@ -4624,4 +4609,12 @@ class learnpathItem
return true;
}
/**
* @return int
*/
public function getLastScormSessionTime()
{
return $this->last_scorm_session_time;
}
}

@ -119,7 +119,6 @@ $htmlHeadXtra[] = '<script type="text/javascript" src="'.api_get_path(WEB_LIBRAR
$tpl = new Template(null);
$tpl->assign('unique_file_id', api_get_unique_id());
$tpl->assign('course_code', api_get_course_id());
$tpl->assign('php_session_id', session_id());
$tpl->assign('filename', $lp_item->get_title().'_nano.wav');
$tpl->assign('enable_record_audio', api_get_setting('enable_record_audio') === 'true');
$tpl->assign('cur_dir_path', '/audio');

@ -28,10 +28,10 @@ require_once __DIR__.'/../inc/global.inc.php';
*/
function initialize_item($lp_id, $user_id, $view_id, $next_item)
{
global $debug;
$debug = 0;
$return = '';
if ($debug > 0) {
error_log('In initialize_item('.$lp_id.','.$user_id.','.$view_id.','.$next_item.')', 0);
if ($debug) {
error_log('In initialize_item('.$lp_id.','.$user_id.','.$view_id.','.$next_item.')');
}
/*$item_id may be one of:
* -'next'
@ -42,18 +42,18 @@ function initialize_item($lp_id, $user_id, $view_id, $next_item)
*/
$mylp = learnpath::getLpFromSession(api_get_course_id(), $lp_id, $user_id);
$mylp->set_current_item($next_item);
if ($debug > 1) {
error_log('In initialize_item() - new item is '.$next_item, 0);
if ($debug) {
error_log('In initialize_item() - new item is '.$next_item);
}
$mylp->start_current_item(true);
if (is_object($mylp->items[$next_item])) {
if ($debug > 1) {
if ($debug) {
error_log('In initialize_item - recovering existing item object '.$next_item, 0);
}
$mylpi = $mylp->items[$next_item];
} else {
if ($debug > 1) {
if ($debug) {
error_log('In initialize_item - generating new item object '.$next_item, 0);
}
$mylpi = new learnpathItem($next_item, $user_id);
@ -141,10 +141,6 @@ function initialize_item($lp_id, $user_id, $view_id, $next_item)
* -lms_view_id
* -lms_user_id
*/
$mytotal = $mylp->getTotalItemsCountWithoutDirs();
$mycomplete = $mylp->get_complete_items_count();
$myprogress_mode = $mylp->get_progress_bar_mode();
$myprogress_mode = ($myprogress_mode == '' ? '%' : $myprogress_mode);
$mynext = $mylp->get_next_item_id();
$myprevious = $mylp->get_previous_item_id();
$myitemtype = $mylpi->get_type();
@ -152,9 +148,7 @@ function initialize_item($lp_id, $user_id, $view_id, $next_item)
$mycredit = $mylpi->get_credit();
$mylaunch_data = $mylpi->get_launch_data();
$myinteractions_count = $mylpi->get_interactions_count();
$myobjectives_count = $mylpi->get_objectives_count();
$mycore_exit = $mylpi->get_core_exit();
$return .=
"olms.lms_lp_id=".$lp_id.";".
"olms.lms_item_id=".$next_item.";".
@ -176,11 +170,10 @@ function initialize_item($lp_id, $user_id, $view_id, $next_item)
$mylp->set_error_msg('');
$mylp->prerequisites_match(); // Check the prerequisites are all complete.
if ($debug > 1) {
if ($debug) {
error_log('Prereq_match() returned '.htmlentities($mylp->error), 0);
}
if ($debug > 1) {
error_log("return = $return ");
error_log("mylp->lp_view_session_id: ".$mylp->lp_view_session_id);
}
return $return;

@ -60,11 +60,11 @@ function save_item(
$userNavigatesAway = 0,
$statusSignalReceived = 0
) {
//global $debug;
$debug = 0;
$return = null;
if ($debug > 0) {
error_log('--------------------------------------');
error_log('lp_ajax_save_item.php : save_item() params: ');
error_log("item_id: $item_id");
error_log("lp_id: $lp_id - user_id: - $user_id - view_id: $view_id - item_id: $item_id");
@ -478,7 +478,9 @@ function save_item(
$myLP->save_last();
Session::write('lpobject', serialize($myLP));
Session::write('oLP', $myLP);
if ($debug > 0) {
error_log("lp_view_session_id :".$myLP->lp_view_session_id);
error_log('---------------- lp_ajax_save_item.php : save_item end ----- ');
}

@ -6,18 +6,4 @@
*
* @author Yannick Warnier <ywarnier@beeznest.org>
*/
/**
* Start a timer and hand it back to the JS by assigning the current time (of start) to
* var asset_timer.
*
* @return string JavaScript time intializer
*/
function start_timer()
{
$time = time();
return $time; //"olms.asset_timer='$time'; olms.asset_timer_total = 0;";
}
echo start_timer();
echo time();

@ -52,7 +52,7 @@ function switch_item_details($lp_id, $user_id, $view_id, $current_item, $next_it
$mylp->next();
$new_item_id = $mylp->get_current_item_id();
if ($debug > 1) {
error_log('In {next} - next item is '.$new_item_id.'(current: '.$current_item.')', 0);
error_log('In {next} - next item is '.$new_item_id.'(current: '.$current_item.')');
}
break;
case 'previous':
@ -60,7 +60,7 @@ function switch_item_details($lp_id, $user_id, $view_id, $current_item, $next_it
$mylp->previous();
$new_item_id = $mylp->get_current_item_id();
if ($debug > 1) {
error_log('In {previous} - next item is '.$new_item_id.'(current: '.$current_item.')', 0);
error_log('In {previous} - next item is '.$new_item_id.'(current: '.$current_item.')');
}
break;
case 'first':
@ -68,7 +68,7 @@ function switch_item_details($lp_id, $user_id, $view_id, $current_item, $next_it
$mylp->first();
$new_item_id = $mylp->get_current_item_id();
if ($debug > 1) {
error_log('In {first} - next item is '.$new_item_id.'(current: '.$current_item.')', 0);
error_log('In {first} - next item is '.$new_item_id.'(current: '.$current_item.')');
}
break;
case 'last':
@ -82,7 +82,7 @@ function switch_item_details($lp_id, $user_id, $view_id, $current_item, $next_it
$new_item_id = $next_item;
$mylp->set_current_item($new_item_id);
if ($debug > 1) {
error_log('In {default} - next item is '.$new_item_id.'(current: '.$current_item.')', 0);
error_log('In {default} - next item is '.$new_item_id.'(current: '.$current_item.')');
}
break;
}
@ -123,7 +123,9 @@ function switch_item_details($lp_id, $user_id, $view_id, $current_item, $next_it
$mylaunch_data = $mylpi->get_launch_data();
/*
if ($mylpi->get_type() == 'asset') {
// Temporary measure to save completion of an asset. Later on, Chamilo should trigger something on unload, maybe... (even though that would mean the last item cannot be completed)
// Temporary measure to save completion of an asset. Later on,
// Chamilo should trigger something on unload, maybe...
// (even though that would mean the last item cannot be completed)
$mylesson_status = 'completed';
$mylpi->set_status('completed');
$mylpi->save();
@ -229,6 +231,7 @@ function switch_item_details($lp_id, $user_id, $view_id, $current_item, $next_it
// Save the new item ID for the exercise tool to use.
Session::write('scorm_item_id', $new_item_id);
Session::write('lpobject', serialize($mylp));
Session::write('oLP', $mylp);
return $return;
}

@ -161,6 +161,7 @@ function switch_item_toc($lpId, $userId, $viewId, $currentItem, $nextItem)
}
Session::write('scorm_item_id', $newItemId);
Session::write('lpobject', serialize($myLP));
Session::write('oLP', $myLP);
return $return;
}

@ -14,13 +14,13 @@ require_once __DIR__.'/../inc/global.inc.php';
$debug = 0;
if ($debug > 0) {
error_log('New lp - In lp_content.php', 0);
error_log('New lp - In lp_content.php');
}
if (empty($lp_controller_touched)) {
if ($debug > 0) {
error_log('New lp - In lp_content.php - Redirecting to lp_controller', 0);
error_log('New lp - In lp_content.php - Redirecting to lp_controller');
}
header('location: lp_controller.php?action=content&lp_id='.intval($_REQUEST['lp_id']).'&item_id='.intval($_REQUEST['item_id']).'&'.api_get_cidreq());
header('Location: lp_controller.php?action=content&lp_id='.intval($_REQUEST['lp_id']).'&item_id='.intval($_REQUEST['item_id']).'&'.api_get_cidreq());
exit;
}
@ -35,7 +35,9 @@ $lp_item_id = $learnPath->get_current_item_id();
*/
$src = '';
if ($debug > 0) {
error_log('New lp - In lp_content.php - Looking for file url', 0);
error_log('New lp - In lp_content.php - Looking for file url');
error_log("lp_type $lp_type");
error_log("lp_item_id $lp_item_id");
}
$list = $learnPath->get_toc();
@ -93,7 +95,7 @@ if ($dir) {
}
if ($debug > 0) {
error_log('New lp - In lp_content.php - File url is '.$src, 0);
error_log('New lp - In lp_content.php - File url is '.$src);
}
$learnPath->set_previous_item($lp_item_id);
@ -114,7 +116,7 @@ $save_setting = api_get_setting('show_navigation_menu');
global $_setting;
$_setting['show_navigation_menu'] = false;
if ($debug > 0) {
error_log('New LP - In lp_content.php - Loading '.$src, 0);
error_log('New LP - In lp_content.php - Loading '.$src);
}
Session::write('oLP', $learnPath);
header("Location: ".urldecode($src));

@ -16,28 +16,18 @@ use ChamiloSession as Session;
// Flag to allow for anonymous user - needs to be set before global.inc.php.
$use_anonymous = true;
$debug = 0;
if ($debug > 0) {
error_log('New LP -+- Entered lp_controller.php -+- (action: '.$_REQUEST['action'].')', 0);
}
// Language files that needs to be included.
if (isset($_GET['action'])) {
if ($_GET['action'] === 'export') {
// Only needed on export.
$language_file[] = 'hotspot';
}
if ($debug) {
error_log('Entering lp_controller.php. Checking if LP exist in current session');
}
// Including the global initialization file.
require_once __DIR__.'/../inc/global.inc.php';
$current_course_tool = TOOL_LEARNPATH;
$_course = api_get_course_info();
$glossaryExtraTools = api_get_setting('show_glossary_in_extra_tools');
$showGlossary = in_array($glossaryExtraTools, ['true', 'lp', 'exercise_and_lp']);
if ($showGlossary) {
if (api_get_setting('show_glossary_in_documents') === 'ismanual' ||
api_get_setting('show_glossary_in_documents') === 'isautomatic'
@ -219,7 +209,7 @@ if ($refresh == 1) {
}
if ($debug > 0) {
error_log('New LP - $myrefresh: '.$myrefresh);
error_log(' $myrefresh: '.$myrefresh);
}
if (!empty($_REQUEST['dialog_box'])) {
@ -230,24 +220,27 @@ $lp_controller_touched = 1;
$lp_found = false;
$lpObject = Session::read('lpobject');
if (!empty($lpObject)) {
if ($debug > 0) {
error_log('New LP - SESSION[lpobject] is defined', 0);
if ($debug) {
error_log(' SESSION[lpobject] is defined');
}
$oLP = unserialize($lpObject);
if (isset($oLP) && is_object($oLP)) {
if ($debug > 0) {
error_log('New LP - oLP is object', 0);
if ($debug) {
error_log(' oLP is object');
}
if ($myrefresh == 1 ||
empty($oLP->cc) ||
$oLP->cc != api_get_course_id() ||
$oLP->lp_view_session_id != $session_id
) {
if ($debug > 0) {
error_log('New LP - Course has changed, discard lp object');
error_log('New LP - $oLP->lp_view_session_id: '.$oLP->lp_view_session_id);
error_log('New LP - $oLP->cc: '.$oLP->cc);
if ($debug) {
error_log('Course has changed, discard lp object');
error_log('$oLP->lp_view_session_id: '.$oLP->lp_view_session_id);
error_log('api_get_session_id(): '.$session_id);
error_log('$oLP->cc: '.$oLP->cc);
error_log('api_get_course_id(): '.api_get_course_id());
}
if ($myrefresh == 1) {
$myrefresh_id = $oLP->get_id();
}
@ -260,21 +253,20 @@ if (!empty($lpObject)) {
}
}
}
if ($debug) {
error_log('$lp_found: '.$lp_found);
}
$course_id = api_get_course_int_id();
if ($debug > 0) {
error_log('New LP - Passed data remains check', 0);
}
if (!$lp_found || (!empty($_REQUEST['lp_id']) && $_SESSION['oLP']->get_id() != $_REQUEST['lp_id'])) {
if ($debug > 0) {
error_log('New LP - oLP is not object, has changed or refresh been asked, getting new', 0);
error_log(' oLP is not object, has changed or refresh been asked, getting new');
}
// Regenerate a new lp object? Not always as some pages don't need the object (like upload?)
if (!empty($_REQUEST['lp_id']) || !empty($myrefresh_id)) {
if ($debug > 0) {
error_log('New LP - lp_id is defined', 0);
error_log(' lp_id is defined');
}
// Select the lp in the database and check which type it is (scorm/dokeos/aicc) to generate the
// right object.
@ -288,7 +280,7 @@ if (!$lp_found || (!empty($_REQUEST['lp_id']) && $_SESSION['oLP']->get_id() != $
if (is_numeric($lp_id)) {
$sel = "SELECT iid, lp_type FROM $lp_table WHERE c_id = $course_id AND id = $lp_id";
if ($debug > 0) {
error_log('New LP - querying '.$sel, 0);
error_log(' querying '.$sel);
}
$res = Database::query($sel);
if (Database::num_rows($res)) {
@ -296,7 +288,8 @@ if (!$lp_found || (!empty($_REQUEST['lp_id']) && $_SESSION['oLP']->get_id() != $
$lpIid = $row['iid'];
$type = $row['lp_type'];
if ($debug > 0) {
error_log('New LP - found row - type '.$type.' - Calling constructor with '.api_get_course_id().' - '.$lp_id.' - '.api_get_user_id(), 0);
error_log('Found row type '.$type);
error_log('Calling constructor: '.api_get_course_id().' - '.$lp_id.' - '.api_get_user_id());
}
switch ($type) {
case 1:
@ -304,7 +297,7 @@ if (!$lp_found || (!empty($_REQUEST['lp_id']) && $_SESSION['oLP']->get_id() != $
if ($oLP !== false) {
$lp_found = true;
} else {
error_log($oLP->error, 0);
error_log($oLP->error);
}
break;
case 2:
@ -312,7 +305,7 @@ if (!$lp_found || (!empty($_REQUEST['lp_id']) && $_SESSION['oLP']->get_id() != $
if ($oLP !== false) {
$lp_found = true;
} else {
error_log($oLP->error, 0);
error_log($oLP->error);
}
break;
case 3:
@ -320,7 +313,7 @@ if (!$lp_found || (!empty($_REQUEST['lp_id']) && $_SESSION['oLP']->get_id() != $
if ($oLP !== false) {
$lp_found = true;
} else {
error_log($oLP->error, 0);
error_log($oLP->error);
}
break;
default:
@ -328,19 +321,19 @@ if (!$lp_found || (!empty($_REQUEST['lp_id']) && $_SESSION['oLP']->get_id() != $
if ($oLP !== false) {
$lp_found = true;
} else {
error_log($oLP->error, 0);
error_log($oLP->error);
}
break;
}
}
} else {
if ($debug > 0) {
error_log('New LP - Request[lp_id] is not numeric', 0);
error_log(' Request[lp_id] is not numeric');
}
}
} else {
if ($debug > 0) {
error_log('New LP - Request[lp_id] and refresh_id were empty', 0);
error_log(' Request[lp_id] and refresh_id were empty');
}
}
if ($lp_found) {
@ -349,7 +342,7 @@ if (!$lp_found || (!empty($_REQUEST['lp_id']) && $_SESSION['oLP']->get_id() != $
}
if ($debug > 0) {
error_log('New LP - Passed oLP creation check', 0);
error_log('Passed oLP creation check', 0);
}
$is_allowed_to_edit = api_is_allowed_to_edit(false, true, false, false);
@ -379,6 +372,10 @@ if (isset($_GET['isStudentView']) && $_GET['isStudentView'] == 'true') {
$action = !empty($_REQUEST['action']) ? $_REQUEST['action'] : '';
if ($debug) {
error_log('Entered lp_controller.php -+- (action: '.$action.')');
}
// format title to be displayed correctly if QUIZ
$post_title = '';
if (isset($_POST['title'])) {
@ -394,10 +391,10 @@ if (isset($_POST['title'])) {
$redirectTo = '';
if ($debug > 0) {
error_log('New LP - action "'.$action.'" triggered');
error_log('action "'.$action.'" triggered');
if (!$lp_found) {
//check if the learnpath ID was defined, otherwise send back to list
error_log('New LP - No learnpath given');
error_log('No learnpath given');
}
}
@ -1031,7 +1028,7 @@ switch ($action) {
$extraFieldValue = new ExtraFieldValue('lp');
$params = [
'lp_id' => $_SESSION['oLP']->id,
'lp_id' => $_SESSION['oLP']->lp_id,
];
$extraFieldValue->saveFieldValues($_REQUEST);
@ -1153,21 +1150,22 @@ switch ($action) {
break;
case 'content':
if ($debug > 0) {
error_log('New LP - Item id is '.intval($_GET['item_id']), 0);
error_log('lp_controller: action: content');
error_log('Item id is '.intval($_GET['item_id']));
}
if (!$lp_found) {
require 'lp_list.php';
} else {
if ($debug > 0) {
error_log('New LP - save_last()', 0);
error_log('save_last()');
}
$_SESSION['oLP']->save_last();
if ($debug > 0) {
error_log('New LP - set_current_item()', 0);
error_log('set_current_item('.$_GET['item_id'].')');
}
$_SESSION['oLP']->set_current_item($_GET['item_id']);
if ($debug > 0) {
error_log('New LP - start_current_item()', 0);
error_log('start_current_item()');
}
$_SESSION['oLP']->start_current_item();
require 'lp_content.php';
@ -1178,7 +1176,7 @@ switch ($action) {
require 'lp_list.php';
} else {
if ($debug > 0) {
error_log('New LP - Trying to set current item to '.$_REQUEST['item_id'], 0);
error_log('Trying to set current item to '.$_REQUEST['item_id'], 0);
}
if (!empty($_REQUEST['item_id'])) {
$_SESSION['oLP']->set_current_item($_REQUEST['item_id']);
@ -1269,12 +1267,18 @@ switch ($action) {
$_SESSION['oLP']->save_current();
$_SESSION['oLP']->save_last();
if ($debug > 0) {
error_log('New LP - save_current()');
error_log('New LP - save_last()');
error_log('save_current()');
error_log('save_last()');
}
$url = api_get_path(WEB_COURSE_PATH).api_get_course_path().'/index.php?id_session='.api_get_session_id();
if (isset($_GET['redirectTo']) && $_GET['redirectTo'] == 'lp_list') {
$url = 'lp_controller.php?'.api_get_cidreq();
$redirectTo = isset($_GET['redirectTo']) ? $_GET['redirectTo'] : '';
switch ($redirectTo) {
case 'lp_list':
$url = 'lp_controller.php?'.api_get_cidreq();
break;
case 'my_courses':
$url = api_get_path(WEB_PATH).'user_portal.php';
break;
}
header('location: '.$url);
exit;
@ -1291,7 +1295,7 @@ switch ($action) {
require 'lp_list.php';
} else {
if ($debug > 0) {
error_log('New LP - Trying to impress this LP item to '.$_REQUEST['item_id'], 0);
error_log('Trying to impress this LP item to '.$_REQUEST['item_id'], 0);
}
if (!empty($_REQUEST['item_id'])) {
$_SESSION['oLP']->set_current_item($_REQUEST['item_id']);
@ -1458,7 +1462,7 @@ switch ($action) {
if (!empty($_SESSION['oLP'])) {
$_SESSION['lpobject'] = serialize($_SESSION['oLP']);
if ($debug > 0) {
error_log('New LP - lpobject is serialized in session', 0);
error_log('lpobject is serialized in session', 0);
}
}

@ -644,13 +644,13 @@ foreach ($categories as $item) {
/* Export */
if ($details['lp_type'] == 1) {
$dsp_disk = Display::url(
Display::return_icon('cd.png', get_lang('Export')),
Display::return_icon('cd.png', get_lang('ExportShort')),
api_get_self()."?".api_get_cidreq()
."&action=export&lp_id=$id"
);
} elseif ($details['lp_type'] == 2) {
$dsp_disk = Display::url(
Display::return_icon('cd.png', get_lang('Export')),
Display::return_icon('cd.png', get_lang('ExportShort')),
api_get_self()."?".api_get_cidreq()
."&action=export&lp_id=$id&export_name="
.api_replace_dangerous_char($name).".zip"
@ -658,7 +658,7 @@ foreach ($categories as $item) {
} else {
$dsp_disk = Display::return_icon(
'cd_na.png',
get_lang('Export')
get_lang('ExportShort')
);
}
@ -886,6 +886,12 @@ foreach ($categories as $item) {
];
}
// Deleting the objects
Session::erase('oLP');
Session::erase('lpobject');
learnpath::generate_learning_path_folder($courseInfo);
DocumentManager::removeGeneratedAudioTempFile();
$template = new Template($nameTools);
$template->assign('subscription_settings', $subscriptionSettings);
$template->assign('is_allowed_to_edit', $is_allowed_to_edit);
@ -901,9 +907,3 @@ $templateName = $template->get_template('learnpath/list.tpl');
$content = $template->fetch($templateName);
$template->assign('content', $content);
$template->display_one_col_template();
learnpath::generate_learning_path_folder($courseInfo);
// Deleting the objects
Session::erase('oLP');
Session::erase('lpobject');
DocumentManager::removeGeneratedAudioTempFile();

@ -18,7 +18,8 @@ $htmlHeadXtra[] = '<script>
var chamilo_xajax_handler = window.parent.oxajax;
</script>';
$lpItemId = isset($_REQUEST['lp_item']) ? intval($_REQUEST['lp_item']) : 0;
$lpItemId = isset($_REQUEST['lp_item']) ? (int) $_REQUEST['lp_item'] : 0;
$lpId = isset($_REQUEST['lp_id']) ? (int) $_REQUEST['lp_id'] : 0;
if (!$lpItemId) {
echo '';
@ -27,29 +28,25 @@ if (!$lpItemId) {
$progress_bar = '';
$navigation_bar = '';
$display_mode = '';
$autostart = 'true';
$myLP = learnpath::getLpFromSession(api_get_course_id(), '', '');
$myLP = learnpath::getLpFromSession(api_get_course_id(), $lpId, api_get_user_id());
if ($myLP) {
$display_mode = $myLP->mode;
$scorm_css_header = true;
$lp_theme_css = $myLP->get_theme();
$my_style = api_get_visual_theme();
// Setting up the CSS theme if exists
$mycourselptheme = null;
$myCourseLpTheme = null;
if (api_get_setting('allow_course_theme') === 'true') {
$mycourselptheme = api_get_course_setting('allow_learning_path_theme');
$myCourseLpTheme = api_get_course_setting('allow_learning_path_theme');
}
if (!empty($lp_theme_css) && !empty($mycourselptheme) && $mycourselptheme != -1 && $mycourselptheme == 1) {
if (!empty($lp_theme_css) && !empty($myCourseLpTheme) && $myCourseLpTheme != -1 && $myCourseLpTheme == 1) {
global $lp_theme_css;
} else {
$lp_theme_css = $my_style;
}
$progress_bar = $myLP->getProgressBar();
$navigation_bar = $myLP->get_navigation_bar();
$mediaplayer = $myLP->get_mediaplayer($lpItemId, $autostart);

@ -119,7 +119,6 @@ foreach ($subscribedUsers as $user) {
// Getting subscribed users to a category.
$subscribedUsersInCategory = $category->getUsers();
$selectedChoices = [];
foreach ($subscribedUsersInCategory as $item) {
$selectedChoices[] = $item->getUser()->getId();
@ -138,7 +137,6 @@ $userMultiSelect = $formUsers->addElement(
$formUsers->addButtonSave(get_lang('Save'));
$defaults = [];
if (!empty($selectedChoices)) {
$defaults['users'] = $selectedChoices;
}

@ -0,0 +1,79 @@
<?php
/* For licensing terms, see /license.txt */
/**
* This is a learning path creation and player tool in Chamilo - previously.
*
* @author Julio Montoya - Improving the list of templates
*
* @package chamilo.learnpath
*/
$this_section = SECTION_COURSES;
require_once __DIR__.'/../inc/global.inc.php';
api_protect_course_script();
$allow = api_is_allowed_to_edit(null, true);
$lpId = !empty($_GET['lp_id']) ? intval($_GET['lp_id']) : 0;
if (!$allow || empty($lpId)) {
api_not_allowed(true);
}
$lp = new learnpath(api_get_course_id(), $lpId, api_get_user_id());
if (api_is_in_gradebook()) {
$interbreadcrumb[] = [
'url' => Category::getUrl(),
'name' => get_lang('ToolGradebook'),
];
}
$interbreadcrumb[] = [
'url' => 'lp_controller.php?action=list&'.api_get_cidreq(),
'name' => get_lang('LearningPaths'),
];
$interbreadcrumb[] = [
'url' => api_get_self()."?action=build&lp_id=$lpId&".api_get_cidreq(),
'name' => $lp->get_name(),
];
$form = new FormValidator(
'',
'POST',
api_get_self().'?'.api_get_cidreq().'&lp_id='.$lpId,
'',
[
'id' => "upload_form",
'enctype' => "multipart/form-data",
]
);
$form->addHeader(get_lang('UpdateFile'));
$form->addHtml(Display::return_message(get_lang('TheScormPackageWillBeUpdatedYouMustUploadTheFileWithTheSameName')));
$form->addLabel(null, Display::return_icon('scorm_logo.jpg', null, ['style' => 'width:230px;height:100px']));
$form->addElement('hidden', 'curdirpath', '');
$form->addElement('file', 'user_file', get_lang('FileToUpload'));
$form->addRule('user_file', get_lang('ThisFieldIsRequired'), 'required');
$form->addButtonUpload(get_lang('Upload'));
if ($form->validate()) {
$oScorm = new scorm();
$manifest = $oScorm->import_package(
$_FILES['user_file'],
'',
api_get_course_info(),
true,
$lp
);
if ($manifest) {
Display::addFlash(Display::return_message(get_lang('Updated')));
}
header('Location: '.api_get_path(WEB_CODE_PATH).'lp/lp_list.php?'.api_get_cidreq());
exit;
}
$content = $form->returnForm();
$tpl = new Template(null);
$tpl->assign('content', $content);
$tpl->display_one_col_template();

@ -276,16 +276,13 @@ if (!empty($_REQUEST['exeId']) &&
if ($safe_id == strval(intval($safe_id)) &&
$safe_item_id == strval(intval($safe_item_id))
) {
$sql = 'SELECT start_date, exe_date, exe_result, exe_weighting, exe_exo_id
$sql = 'SELECT start_date, exe_date, exe_result, exe_weighting, exe_exo_id, exe_duration
FROM '.$TBL_TRACK_EXERCICES.'
WHERE exe_id = '.$safe_exe_id;
$res = Database::query($sql);
$row_dates = Database::fetch_array($res);
$time_start_date = api_strtotime($row_dates['start_date'], 'UTC');
$time_exe_date = api_strtotime($row_dates['exe_date'], 'UTC');
$mytime = (int) $time_exe_date - (int) $time_start_date;
$duration = (int) $row_dates['exe_duration'];
$score = (float) $row_dates['exe_result'];
$max_score = (float) $row_dates['exe_weighting'];
@ -326,7 +323,7 @@ if (!empty($_REQUEST['exeId']) &&
$sql = "UPDATE $TBL_LP_ITEM_VIEW SET
status = '$status',
score = $score,
total_time = $mytime
total_time = $duration
WHERE iid = $lp_item_view_id";
if ($debug) {
error_log($sql);
@ -438,10 +435,16 @@ if ($is_allowed_to_edit) {
}
$buttonHomeText = get_lang('CourseHomepageLink');
// Return to lp list
if (api_get_course_setting('lp_return_link') == 1) {
$buttonHomeUrl .= '&redirectTo=lp_list';
$buttonHomeText = get_lang('LearningPathList');
$returnLink = api_get_course_setting('lp_return_link');
switch ($returnLink) {
case 1: // lp list
$buttonHomeUrl .= '&redirectTo=lp_list';
$buttonHomeText = get_lang('LearningPathList');
break;
case 2: // user portal
$buttonHomeUrl .= '&redirectTo=my_courses';
$buttonHomeText = get_lang('MyCourses');
break;
}
$lpPreviewImagePath = Display::returnIconPath('unknown.png', ICON_SIZE_BIG);
@ -542,7 +545,7 @@ $template->display_no_layout_template();
// Restore a global setting.
$_setting['show_navigation_menu'] = $save_setting;
Session::write('lp', $lp);
Session::write('oLP', $lp);
if ($debug) {
error_log(' ------- end lp_view.php ------');

@ -211,7 +211,6 @@ class OpenOfficeTextDocument extends OpenofficeDocument
$_course = api_get_course_info();
// Split document to pages.
$pages = explode('||page_break||', $body);
$first_item = 0;
foreach ($pages as $key => $page_content) {
// For every pages, we create a new file.
$key += 1;

@ -1666,7 +1666,7 @@ function switch_item(current_item, next_item){
// (4) refresh the audio player if needed
$.ajax({
type: "POST",
url: "lp_nav.php"+courseUrl,
url: "lp_nav.php"+courseUrl+ "&lp_id=" + olms.lms_lp_id,
data: {
lp_item: next_item
},

@ -54,7 +54,12 @@ if (empty($courseId)) {
$courseInfo = api_get_course_info_by_id($courseId);
if (!empty($courseInfo)) {
$form->addHidden('course_id', $courseId);
$form->addLabel(get_lang('Course'), $courseInfo['name'].' ('.$courseInfo['code'].')');
$courseLabel = Display::url(
$courseInfo['name'].' ('.$courseInfo['code'].')',
$courseInfo['course_public_url'],
['target' => '_blank']
);
$form->addLabel(get_lang('Course'), $courseLabel);
$exerciseList = ExerciseLib::get_all_exercises_for_course_id(
$courseInfo,
0,

@ -220,6 +220,21 @@ switch ($action) {
exit;
}
break;
case 'generate_certificate':
// Delete old certificate
$myCertificate = GradebookUtils::get_certificate_by_user_id(
0,
$student_id
);
if ($myCertificate) {
$certificate = new Certificate($myCertificate['id'], $student_id);
$certificate->delete(true);
}
// Create new one
$certificate = new Certificate(0, $student_id);
$certificate->generatePdfFromCustomCertificate();
exit;
break;
case 'send_legal':
$subject = get_lang('SendLegalSubject');
$content = sprintf(
@ -878,13 +893,13 @@ if (empty($details)) {
$progress = Tracking::get_avg_student_progress(
$user_info['user_id'],
$courseCodeItem,
null,
[],
$sId
);
$score = Tracking:: get_avg_student_score(
$user_info['user_id'],
$courseCodeItem,
null,
[],
$sId
);
$progress = empty($progress) ? '0%' : $progress.'%';
@ -1479,7 +1494,8 @@ if (empty($details)) {
echo '<tr>';
echo '<td>'.$work->title.'</td>';
$documentNumber = $key + 1;
echo '<td class="text-center"><a href="'.api_get_path(WEB_CODE_PATH).'work/view.php?cidReq='.$course_code.'&id_session='.$sessionId.'&id='.$results['id'].'">('.$documentNumber.')</a></td>';
$url = api_get_path(WEB_CODE_PATH).'work/view.php?cidReq='.$course_code.'&id_session='.$sessionId.'&id='.$results['id'];
echo '<td class="text-center"><a href="'.$url.'">('.$documentNumber.')</a></td>';
$qualification = !empty($results['qualification']) ? $results['qualification'] : '-';
echo '<td class="text-center">'.$qualification.'</td>';
echo '<td class="text-center">'.$results['formatted_date'].'</td>';
@ -1503,7 +1519,6 @@ if (empty($details)) {
echo '<td class="text-center">'.$field->getValue().'</td>';
}
}
echo '</tr>';
}
}
@ -1588,10 +1603,12 @@ if (empty($details)) {
</div>
<?php
} //end details
echo Tracking::displayUserSkills(
$user_info['user_id'],
$courseInfo ? $courseInfo['real_id'] : 0,
$sessionId
$sessionId,
api_get_configuration_value('allow_teacher_access_student_skills')
);
if ($allowMessages === true) {
@ -1643,7 +1660,7 @@ if ($allowMessages === true) {
$form = new FormValidator(
'messages',
'post',
api_get_self().'?action=send_message&student='.$student_id
$currentUrl.'&action=send_message'
);
$form->addHtml('<div id="compose_message" style="display:none;">');
$form->addText('subject', get_lang('Subject'));

@ -107,16 +107,15 @@ if ($action === 'addnote') {
Security::clear_token();
NotebookManager::display_notes();
} else {
echo '<div class="actions">';
echo '<a href="index.php">'.
Display::return_icon(
'back.png',
get_lang('BackToNotesList'),
'',
ICON_SIZE_MEDIUM
).
'</a>';
echo '</div>';
echo Display::toolbarAction(
'add_glossary',
[
Display::url(
Display::return_icon('back.png', get_lang('Back'), [], ICON_SIZE_MEDIUM),
api_get_self().'?'.api_get_cidreq()
),
]
);
$token = Security::get_token();
$form->addElement('hidden', 'sec_token');
$form->setConstants(['sec_token' => $token]);
@ -171,16 +170,15 @@ if ($action === 'addnote') {
Security::clear_token();
NotebookManager::display_notes();
} else {
echo '<div class="actions">';
echo '<a href="index.php">'.
Display::return_icon(
'back.png',
get_lang('BackToNotesList'),
'',
ICON_SIZE_MEDIUM
).
'</a>';
echo '</div>';
echo Display::toolbarAction(
'add_glossary',
[
Display::url(
Display::return_icon('back.png', get_lang('Back'), [], ICON_SIZE_MEDIUM),
api_get_self().'?'.api_get_cidreq()
),
]
);
$token = Security::get_token();
$form->addElement('hidden', 'sec_token');
$form->setConstants(['sec_token' => $token]);

@ -1,6 +1,7 @@
<?php
/* For licensing terms, see /license.txt */
use Chamilo\CoreBundle\Entity\Course;
use Chamilo\CoreBundle\Entity\Promotion;
use Chamilo\CoreBundle\Entity\Repository\SequenceRepository;
use Chamilo\CoreBundle\Entity\Repository\SessionRepository;
@ -158,6 +159,9 @@ if ($sessionInfo['nbr_courses'] == 0) {
$courseItem = '';
$courses = $sessionRepository->getCoursesOrderedByPosition($session);
$allowSkills = api_get_configuration_value('allow_skill_rel_items');
/** @var Course $course */
foreach ($courses as $course) {
// Select the number of users
$numberOfUsers = SessionManager::getCountUsersInCourseSession(
@ -166,8 +170,7 @@ if ($sessionInfo['nbr_courses'] == 0) {
);
// Get coachs of the courses in session
$namesOfCoaches = [];
$coachSubscriptions = $session
->getUserCourseSubscriptionsByStatus($course, Session::COACH)
$coachSubscriptions = $session->getUserCourseSubscriptionsByStatus($course, Session::COACH)
->forAll(function ($index, SessionRelCourseRelUser $subscription) use (&$namesOfCoaches) {
$namesOfCoaches[] = $subscription->getUser()->getCompleteNameWithUserName();
@ -209,14 +212,20 @@ if ($sessionInfo['nbr_courses'] == 0) {
).'</td>';
$courseItem .= '<td>'.($namesOfCoaches ? implode('<br>', $namesOfCoaches) : get_lang('None')).'</td>';
$courseItem .= '<td>'.$numberOfUsers.'</td>';
$courseItem .= '
<td>
<a href="'.$courseUrl.'">'.
Display::return_icon('course_home.gif', get_lang('Course')).'</a>
'.$orderButtons.'
<a href="session_course_user_list.php?id_session='.$sessionId.'&course_code='.$course->getCode().'">'.
Display::return_icon('user.png', get_lang('Users'), '', ICON_SIZE_SMALL).'</a>
<a href="'.api_get_path(WEB_CODE_PATH).'user/user_import.php?action=import&cidReq='.$course->getCode().'&id_session='.$sessionId.'">'.
$courseItem .= '<td>';
$courseItem .= Display::url(Display::return_icon('course_home.gif', get_lang('Course')), $courseUrl);
if ($allowSkills) {
$courseItem .= Display::url(
Display::return_icon('skills.png', get_lang('Skills')),
api_get_path(WEB_CODE_PATH).'admin/skill_rel_course.php?session_id='.$sessionId.'&course_id='.$course->getId()
);
}
$courseItem .= $orderButtons;
$courseItem .= '<a href="session_course_user_list.php?id_session='.$sessionId.'&course_code='.$course->getCode().'">'.
Display::return_icon('user.png', get_lang('Users'), '', ICON_SIZE_SMALL).'</a>';
$courseItem .= '<a href="'.api_get_path(WEB_CODE_PATH).'user/user_import.php?action=import&cidReq='.$course->getCode().'&id_session='.$sessionId.'">'.
Display::return_icon('import_csv.png', get_lang('ImportUsersToACourse'), null, ICON_SIZE_SMALL).'</a>
<a href="'.api_get_path(WEB_CODE_PATH).'user/user_export.php?file_type=csv&course_session='.$course->getCode().':'.$sessionId.'&addcsvheader=1">'.
Display::return_icon('export_csv.png', get_lang('ExportUsersOfACourse'), null, ICON_SIZE_SMALL).'</a>
@ -225,9 +234,9 @@ if ($sessionInfo['nbr_courses'] == 0) {
<a href="session_course_edit.php?id_session='.$sessionId.'&page=resume_session.php&course_code='.$course->getCode().''.$orig_param.'">'.
Display::return_icon('teacher.png', get_lang('ModifyCoach'), '', ICON_SIZE_SMALL).'</a>
<a href="'.api_get_self().'?id_session='.$sessionId.'&action=delete&idChecked[]='.$course->getCode().'" onclick="javascript:if(!confirm(\''.get_lang('ConfirmYourChoice').'\')) return false;">'.
Display::return_icon('delete.png', get_lang('Delete')).'</a>
</td>
</tr>';
Display::return_icon('delete.png', get_lang('Delete')).'</a>';
$courseItem .= '</td></tr>';
$count++;
}
$courseListToShow .= $courseItem;

@ -100,6 +100,10 @@ switch ($action) {
$res = $object->save($values);
if ($res) {
$extraFieldValue = new ExtraFieldValue('scheduled_announcement');
$values['item_id'] = $res;
$extraFieldValue->saveFieldValues($values);
Display::addFlash(
Display::return_message(
get_lang('ItemAdded'),
@ -122,8 +126,8 @@ switch ($action) {
break;
case 'edit':
// Action handling: Editing
$url = api_get_self().'?action='.Security::remove_XSS($_GET['action']).'&id='.intval($_GET['id']).'&session_id='.$sessionId;
$form = $object->returnSimpleForm($url, 'edit', $sessionInfo);
$url = api_get_self().'?action='.Security::remove_XSS($_GET['action']).'&id='.$id.'&session_id='.$sessionId;
$form = $object->returnSimpleForm($id, $url, 'edit', $sessionInfo);
if ($form->validate()) {
$values = $form->getSubmitValues();
$values['id'] = $id;
@ -131,10 +135,16 @@ switch ($action) {
$values['date'] = api_get_utc_datetime($values['date']);
$res = $object->update($values);
$extraFieldValue = new ExtraFieldValue('scheduled_announcement');
$values['item_id'] = $id;
$extraFieldValue->saveFieldValues($values);
Display::addFlash(Display::return_message(
get_lang('Updated'),
'confirmation'
));
header("Location: $url");
exit;
}
$item = $object->get($id);
$item['date'] = api_get_local_time($item['date']);
@ -142,7 +152,7 @@ switch ($action) {
$content = $form->returnForm();
break;
case 'delete':
$object->delete($_GET['id']);
$object->delete($id);
$content = $object->getGrid($sessionId);
break;
default:

@ -84,7 +84,6 @@ $xajax->processRequests();
$htmlHeadXtra[] = $xajax->getJavascript('../inc/lib/xajax/');
$htmlHeadXtra[] = "
<script>
$(document).ready( function() {
accessSwitcher(0);
});
@ -102,11 +101,10 @@ function accessSwitcher(accessFromReady) {
}
if (access == 1) {
$('#duration').hide();
$('#duration_div').hide();
$('#date_fields').show();
} else {
$('#duration').show();
$('#duration_div').show();
$('#date_fields').hide();
}
emptyDuration();
@ -139,13 +137,14 @@ $form->addElement('header', $tool_name);
$result = SessionManager::setForm($form);
$url = api_get_path(WEB_AJAX_PATH).'session.ajax.php';
$urlUpload = api_get_path(WEB_UPLOAD_PATH);
$sysUploadPath = api_get_path(SYS_UPLOAD_PATH);
$urlAjaxExtraField = api_get_path(WEB_AJAX_PATH).'extra_field.ajax.php?1=1';
$htmlHeadXtra[] = "
<script>
$(function() {
".$result['js']."
$('#system_template').on('change', function() {
var sessionId = $(this).find('option:selected').val();
@ -168,13 +167,48 @@ $(function() {
if (data.duration > 0) {
$('#access').val(0);
$('#access').selectpicker('render');
$('#duration').val(data.duration);
accessSwitcher(0);
$('#duration').val(parseInt(data.duration));
} else {
$('#access').val(1);
$('#access').selectpicker('render');
accessSwitcher(1);
var variables = [
'display_start_date',
'access_start_date',
'coach_access_start_date',
'display_end_date',
'access_end_date',
'coach_access_end_date'
];
variables.forEach(function(variable) {
var variableName = variable + '_to_local_time';
if (data[variableName]) {
var parsedDate = $.datepicker.parseDateTime(
'yy-mm-dd',
'hh:mm:ss',
data[variableName]
);
if (parsedDate) {
$('#'+variable).datetimepicker('setDate', parsedDate);
}
}
});
}
$('[name=\'show_description\']').prop('checked', false);
if (data.show_description) {
$('[name=\'show_description\']').prop('checked', true);
}
$('[name=\'send_subscription_notification\']').prop('checked', false);
if (data.send_subscription_notification) {
$('[name=\'send_subscription_notification\']').prop('checked', true);
}
$.each(data.extra_fields, function(i, item) {
var fieldName = 'extra_'+item.variable;
var fieldName = 'extra_'+item.variable;
/*
const FIELD_TYPE_TEXT = 1;
const FIELD_TYPE_TEXTAREA = 2;
@ -218,7 +252,8 @@ $(function() {
break;
case '4': // simple select
case '5': // multiple select
$('#'+fieldName+'').val(item.value);
var options = item.value.split(';');
$('#'+fieldName+'').val(options);
$('#'+fieldName+'').selectpicker('render');
break;
case '8': // double
@ -227,10 +262,8 @@ $(function() {
// item.value has format : 85::86
if (item.value) {
var values = item.value.split('::');
var firstFieldId = values[0];
var secondFieldId = values[1];
$('#'+first+'').val(firstFieldId);
$('#'+first+'').selectpicker('render');
@ -262,7 +295,6 @@ $(function() {
}
break;
case '10': // tags
// Remove all options
$('#'+fieldName+' option').each(function(i, optionItem) {
$(this).remove();
@ -294,6 +326,27 @@ $(function() {
$('[name=\''+check+'\']').prop('checked', true);
}
break;
case '16':
if (item.value) {
// $('input[name='+fieldName+']').val(item.value);
var url = '".$urlUpload."';
url = url + item.value;
var divFormGroup = fieldName + '-form-group';
var divWrapper = fieldName + '_crop_image';
var divPreview = fieldName + '_preview_image';
var divCropButton = fieldName + '_crop_button';
var cropResult = fieldName + '_crop_result';
$('[name=\''+cropResult+'\']').val('import_file_from_session::' + sessionId);
$('#' + divFormGroup).show();
$('#' + divWrapper).show();
$('#' + divCropButton).hide();
$('#' + divPreview).attr('src', url);
//$('[name=\''+fieldName+'\']')
}
break;
}
});
}
@ -315,7 +368,6 @@ $form->setDefaults($formDefaults);
if ($form->validate()) {
$params = $form->getSubmitValues();
$name = $params['name'];
$startDate = $params['access_start_date'];
$endDate = $params['access_end_date'];
@ -342,10 +394,33 @@ if ($form->validate()) {
}
}
if (isset($extraFields['extra_image']) && $isThisImageCropped) {
if (isset($extraFields['extra_image']) && !empty($extraFields['extra_image']['name']) && $isThisImageCropped) {
$extraFields['extra_image']['crop_parameters'] = $params['picture_crop_result'];
}
// Check if the session image will be copied from the template
$importImageFromSession = false;
$sessionIdToImport = explode('::', $params['extra_image_crop_result']);
$sessionIdToImport = isset($sessionIdToImport[1]) ? (int) $sessionIdToImport[1] : 0;
if (!empty($sessionIdToImport)) {
$extraField = new ExtraField('session');
$extraFieldInfo = $extraField->get_handler_field_info_by_field_variable('image');
$extraFieldValue = new ExtraFieldValue('session');
$extraFieldValueData = $extraFieldValue->get_values_by_handler_and_field_id(
$sessionIdToImport,
$extraFieldInfo['id']
);
if ($extraFieldValueData && file_exists($sysUploadPath.$extraFieldValueData['value'])) {
$extraFields['extra_image']['name'] = basename($extraFieldValueData['value']);
$extraFields['extra_image']['tmp_name'] = $sysUploadPath.$extraFieldValueData['value'];
$extraFields['extra_image']['type'] = 'image/png';
$extraFields['extra_image']['error'] = 0;
$extraFields['extra_image']['size'] = filesize($sysUploadPath.$extraFieldValueData['value']);
}
}
$return = SessionManager::create_session(
$name,
$startDate,

@ -13,7 +13,7 @@ $this_section = SECTION_PLATFORM_ADMIN;
SessionManager::protectSession(null, false);
// Add the JS needed to use the jqgrid
//Add the JS needed to use the jqgrid
$htmlHeadXtra[] = api_get_jqgrid_js();
$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : null;
@ -42,7 +42,7 @@ if ($action == 'delete') {
$tool_name = get_lang('SessionList');
Display::display_header($tool_name);
$courseId = isset($_GET['course_id']) ? $_GET['course_id'] : 0;
$courseId = isset($_GET['course_id']) ? $_GET['course_id'] : null;
$sessionFilter = new FormValidator(
'course_filter',

@ -120,7 +120,8 @@ if (!empty($results)) {
);
$result['picture'] = '<img class="img-responsive" src="'.$picture['file'].'" />';
$group_actions = '<div class="group-more"><a class="btn btn-default" href="groups.php?#tab_browse-2">'.get_lang('SeeMore').'</a></div>';
$group_actions = '<div class="group-more"><a class="btn btn-default" href="groups.php?#tab_browse-2">'.
get_lang('SeeMore').'</a></div>';
$group_info = '<div class="description"><p>'.cut($result['description'], 120, true)."</p></div>";
$groups_newest[] = [
Display::url(

@ -25,7 +25,7 @@ if (!$isStudent && !$isStudentBoss && !$isDRH) {
$action = isset($_GET['a']) ? $_GET['a'] : '';
switch ($action) {
case 'generate_custom_skill':
$certificate = new Certificate(0, api_get_user_id());
$certificate = new Certificate(0, api_get_user_id(), false, false);
$certificate->generatePdfFromCustomCertificate();
break;
}

@ -85,8 +85,9 @@ if ($query != '' || ($query_vars['search_type'] == '1' && count($query_vars) > 2
$buttonClass = 'btn btn-default btn-sm';
foreach ($users as $user) {
$user_info = api_get_user_info($user['id'], true);
$sendInvitation = '<button class="'.$buttonClass.' disabled "><em class="fa fa-user"></em> '.get_lang('SendInvitation').'</button>';
$relation_type = intval(SocialManager::get_relation_between_contacts(api_get_user_id(), $user_info['user_id']));
$sendInvitation = '<button class="'.$buttonClass.' disabled ">
<em class="fa fa-user"></em> '.get_lang('SendInvitation').'</button>';
$relation_type = SocialManager::get_relation_between_contacts(api_get_user_id(), $user_info['user_id']);
$url = api_get_path(WEB_PATH).'main/social/profile.php?u='.$user_info['user_id'];
// Show send invitation icon if they are not friends yet

@ -82,9 +82,13 @@ if ($_GET['action'] == 'edit' && isset($survey_id) && is_numeric($survey_id)) {
if ($link_info) {
$defaults['category_id'] = $link_info['category_id'];
if ($sql_result_array = Database::fetch_array(Database::query('SELECT weight FROM '.$table_gradebook_link.' WHERE id='.$gradebook_link_id))) {
$gradebook_link_id = (int) $gradebook_link_id;
$sql = "SELECT weight FROM $table_gradebook_link WHERE id = $gradebook_link_id";
$result = Database::query($sql);
$gradeBookData = Database::fetch_array($result);
if ($gradeBookData) {
$defaults['survey_qualify_gradebook'] = $gradebook_link_id;
$defaults['survey_weight'] = number_format($sql_result_array['weight'], 2, '.', '');
$defaults['survey_weight'] = number_format($gradeBookData['weight'], 2, '.', '');
}
}
} else {
@ -119,7 +123,7 @@ $survey_code = $form->addElement(
);
if ($_GET['action'] == 'edit') {
//$survey_code->freeze();
$survey_code->freeze();
$form->applyFilter('survey_code', 'api_strtoupper');
}
@ -326,9 +330,7 @@ if ($form->validate()) {
} else {
// Displaying the header
Display::display_header($tool_name);
$form->display();
}
// Footer
Display :: display_footer();
Display::display_footer();

@ -7,11 +7,15 @@ use ChamiloSession as Session;
* @package chamilo.survey
*
* @author unknown, the initial survey that did not make it in 1.8 because of bad code
* @author Patrick Cool <patrick.cool@UGent.be>, Ghent University: cleanup, refactoring and rewriting large parts of the code
* @author Julio Montoya <gugli100@gmail.com>, Chamilo: Personality Test modification and rewriting large parts of the code as well
* @author Patrick Cool <patrick.cool@UGent.be>, Ghent University: cleanup,
* refactoring and rewriting large parts of the code
* @author Julio Montoya <gugli100@gmail.com>, Chamilo: Personality Test
* modification and rewriting large parts of the code as well
*
* @todo check if the user already filled the survey and if this is the case then the answers have to be updated and not stored again.
* @todo performance could be improved if not the survey_id was stored with the invitation but the survey_code
* @todo check if the user already filled the survey and if this
* is the case then the answers have to be updated and not stored again.
* @todo performance could be improved if not the survey_id was
* stored with the invitation but the survey_code
*/
// Unsetting the course id (because it is in the URL)

@ -0,0 +1,59 @@
<?php
/* For licensing terms, see /license.txt */
use Chamilo\CoreBundle\Entity\Course;
use Chamilo\CoreBundle\Entity\Session;
use Chamilo\CourseBundle\Entity\CSurvey;
use Chamilo\CourseBundle\Entity\CSurveyInvitation;
$cidReset = true;
require_once __DIR__.'/../inc/global.inc.php';
api_block_anonymous_users(true);
$em = Database::getManager();
$currentUser = api_get_user_entity(api_get_user_id());
$avatarPath = UserManager::getUserPicture($currentUser->getId());
$pending = SurveyUtil::getUserPendingInvitations($currentUser->getId());
$surveysData = [];
foreach ($pending as $i => $item) {
if (is_a($item, 'Chamilo\CourseBundle\Entity\CSurveyInvitation')) {
continue;
}
/** @var CSurvey $survey */
$survey = $item;
/** @var CSurveyInvitation invitation */
$invitation = $pending[$i + 1];
/** @var Course $course */
$course = $em->find('ChamiloCoreBundle:Course', $survey->getCId());
/** @var Session $session */
$session = $em->find('ChamiloCoreBundle:Session', $survey->getSessionId());
$course = $course ? ['id' => $course->getId(), 'title' => $course->getTitle(), 'code' => $course->getCode()] : null;
$session = $session ? ['id' => $session->getId(), 'name' => $session->getName()] : null;
$surveysData[$survey->getSurveyId()] = [
'title' => $survey->getTitle(),
'invitation_code' => $invitation->getInvitationCode(),
'avail_from' => $survey->getAvailFrom(),
'avail_till' => $survey->getAvailTill(),
'course' => $course,
'session' => $session,
];
}
$toolName = get_lang('PendingSurveys');
$template = new Template($toolName);
$template->assign('user', $currentUser);
$template->assign('user_avatar', $avatarPath);
$template->assign('surveys', $surveysData);
$layout = $template->get_template('survey/pending.tpl');
$content = $template->fetch($layout);
$template->assign('header', $toolName);
$template->assign('content', $content);
$template->display_one_col_template();

@ -5,9 +5,8 @@
* @package chamilo.survey
*
* @author unknown, the initial survey that did not make it in 1.8 because of bad code
* @author Patrick Cool <patrick.cool@UGent.be>, Ghent University: cleanup, refactoring and rewriting large parts of the code
*
* @version $Id: question.php 21734 2009-07-02 17:12:41Z cvargas1 $
* @author Patrick Cool <patrick.cool@UGent.be>, Ghent University: cleanup,
* refactoring and rewriting large parts of the code
*/
require_once __DIR__.'/../inc/global.inc.php';

@ -5,9 +5,8 @@
* @package chamilo.survey
*
* @author unknown, the initial survey that did not make it in 1.8 because of bad code
* @author Patrick Cool <patrick.cool@UGent.be>, Ghent University: cleanup, refactoring and rewriting large parts of the code
*
* @version $Id: reporting.php 21652 2009-06-27 17:07:35Z herodoto $
* @author Patrick Cool <patrick.cool@UGent.be>, Ghent University: cleanup,
* refactoring and rewriting large parts of the code
*
* @todo The question has to be more clearly indicated (same style as when filling the survey)
*/

@ -6,8 +6,6 @@
*
* @author Arnaud Ligot <arnaud@cblue.be>
*
* @version $Id: $
*
* A small peace of code to enable user to access images included into survey
* which are accessible by non authenticated users. This file is included
* by document/download.php
@ -44,7 +42,8 @@ function check_download_survey($course, $invitation, $doc_url)
exit;
}
// Very basic security check: check if a text field from a survey/answer/option contains the name of the document requested
// Very basic security check: check if a text field from
// a survey/answer/option contains the name of the document requested
// Fetch survey ID
// If this is the case there will be a language choice
$sql = "SELECT * FROM $table_survey

@ -30,12 +30,12 @@ class SurveyManager
return false;
}
$course_id = api_get_course_int_id();
$table_survey = Database::get_course_table(TABLE_SURVEY);
$table = Database::get_course_table(TABLE_SURVEY);
$code = Database::escape_string($code);
$num = 0;
$new_code = $code;
while (true) {
$sql = "SELECT * FROM $table_survey
$sql = "SELECT * FROM $table
WHERE code = '$new_code' AND c_id = $course_id";
$result = Database::query($sql);
if (Database::num_rows($result)) {
@ -92,7 +92,6 @@ class SurveyManager
*/
public static function get_surveys($course_code, $session_id = 0)
{
$table_survey = Database::get_course_table(TABLE_SURVEY);
if (empty($course_code)) {
return false;
}
@ -104,7 +103,8 @@ class SurveyManager
$session_condition = api_get_session_condition($session_id, true, true);
$sql = "SELECT * FROM $table_survey
$table = Database::get_course_table(TABLE_SURVEY);
$sql = "SELECT * FROM $table
WHERE c_id = {$course_info['real_id']} $session_condition ";
$result = Database::query($sql);
$result = Database::store_result($result, 'ASSOC');
@ -251,9 +251,7 @@ class SurveyManager
}
$values['anonymous'] = intval($values['anonymous']);
$additional['columns'] = '';
$extraParams = [];
if ($values['anonymous'] == 0) {
// Input_name_list
$values['show_form_profile'] = isset($values['show_form_profile']) ? $values['show_form_profile'] : 0;
@ -409,9 +407,7 @@ class SurveyManager
}
$values['shuffle'] = isset($values['shuffle']) ? $values['shuffle'] : null;
$values['one_question_per_page'] = isset($values['one_question_per_page'])
? $values['one_question_per_page']
: null;
$values['one_question_per_page'] = isset($values['one_question_per_page']) ? $values['one_question_per_page'] : null;
$values['show_form_profile'] = isset($values['show_form_profile']) ? $values['show_form_profile'] : null;
$extraParams = [];
@ -499,7 +495,6 @@ class SurveyManager
}
$gradebook_link_type = 8;
$link_info = GradebookUtils::isResourceInCourseGradebook(
$courseCode,
$gradebook_link_type,
@ -1012,7 +1007,6 @@ class SurveyManager
}
// Getting the information of the question options
$result = Database::query($sqlOption);
while ($row = Database::fetch_array($result, 'ASSOC')) {
/** @todo this should be renamed to options instead of answers */
@ -1084,6 +1078,8 @@ class SurveyManager
* @param array $survey_data
* @param array $form_content all the information of the form
*
* @return string
*
* @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
*
* @version January 2007
@ -1127,7 +1123,6 @@ class SurveyManager
$empty_answer = true;
}
}
$additional = [];
$course_id = api_get_course_int_id();
if (!$empty_answer) {
@ -1393,7 +1388,7 @@ class SurveyManager
*
* @param int $survey_id the id of the survey that has to be deleted
*
* @return true
* @return bool
*
* @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
*
@ -1422,6 +1417,8 @@ class SurveyManager
// Deleting all the answers on this survey
self::delete_all_survey_answers($survey_id);
return true;
}
/**
@ -1440,14 +1437,14 @@ class SurveyManager
public static function delete_survey_question($survey_id, $question_id, $shared = false)
{
$course_id = api_get_course_int_id();
// Table definitions
$table_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
if ($shared) {
self::delete_shared_survey_question($survey_id, $question_id);
}
// Table definitions
$table = Database::get_course_table(TABLE_SURVEY_QUESTION);
// Deleting the survey questions
$sql = "DELETE FROM $table_survey_question
$sql = "DELETE FROM $table
WHERE
c_id = $course_id AND
survey_id='".intval($survey_id)."' AND
@ -1679,9 +1676,9 @@ class SurveyManager
public static function delete_all_survey_answers($survey_id)
{
$course_id = api_get_course_int_id();
$table_survey_answer = Database::get_course_table(TABLE_SURVEY_ANSWER);
$table = Database::get_course_table(TABLE_SURVEY_ANSWER);
$survey_id = intval($survey_id);
$sql = "DELETE FROM $table_survey_answer
$sql = "DELETE FROM $table
WHERE c_id = $course_id AND survey_id=$survey_id";
Database::query($sql);
@ -1697,13 +1694,13 @@ class SurveyManager
*/
public static function is_user_filled_survey($user_id, $survey_id, $course_id)
{
$table_survey_answer = Database::get_course_table(TABLE_SURVEY_ANSWER);
$table = Database::get_course_table(TABLE_SURVEY_ANSWER);
$user_id = intval($user_id);
$course_id = intval($course_id);
$survey_id = intval($survey_id);
$sql = "SELECT DISTINCT user
FROM $table_survey_answer
FROM $table
WHERE
c_id = $course_id AND
user = $user_id AND
@ -1962,8 +1959,8 @@ class SurveyManager
* This function copy survey specifying course id and session id where will be copied.
*
* @param int $surveyId
* @param int $courseId target course id
* @param int $sessionId target session id
* @param int $targetCourseId target course id
* @param int $targetSessionId target session id
*
* @return bool|int when fails or return the new survey id
*/

@ -2829,10 +2829,14 @@ class SurveyUtil
* @param int $survey_id the id of the survey
* @param bool $drh
*
* @return string html code that are the actions that can be performed on any survey
* @throws \Doctrine\ORM\ORMException
* @throws \Doctrine\ORM\OptimisticLockException
* @throws \Doctrine\ORM\TransactionRequiredException
*
* @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
*
* @return string html code that are the actions that can be performed on any survey
*
* @version January 2007
*/
public static function modify_filter($survey_id, $drh = false)
@ -2850,12 +2854,15 @@ class SurveyUtil
}
$survey_id = $survey->getSurveyId();
$return = '';
$actions = [];
$hideReportingButton = api_get_configuration_value('hide_survey_reporting_button');
$codePath = api_get_path(WEB_CODE_PATH);
$params = [];
parse_str(api_get_cidreq(), $params);
$reportingLink = Display::url(
Display::return_icon('statistics.png', get_lang('Reporting'), [], ICON_SIZE_SMALL),
api_get_path(WEB_CODE_PATH).'survey/reporting.php?'.api_get_cidreq().'&survey_id='.$survey_id
Display::return_icon('statistics.png', get_lang('Reporting')),
$codePath.'survey/reporting.php?'.http_build_query($params + ['survey_id' => $survey_id])
);
if ($drh) {
@ -2866,50 +2873,62 @@ class SurveyUtil
if (api_is_allowed_to_edit() ||
api_is_element_in_the_session(TOOL_SURVEY, $survey_id)
) {
$return .= '<a href="'.api_get_path(WEB_CODE_PATH).'survey/create_new_survey.php?'.api_get_cidreq()
.'&action=edit&survey_id='.$survey_id.'">'
.Display::return_icon('edit.png', get_lang('Edit'), '', ICON_SIZE_SMALL)
.'</a>';
$actions[] = Display::url(
Display::return_icon('edit.png', get_lang('Edit')),
$codePath.'survey/create_new_survey.php?'
.http_build_query($params + ['action' => 'edit', 'survey_id' => $survey_id])
);
if (SurveyManager::survey_generation_hash_available()) {
$return .= Display::url(
Display::return_icon('new_link.png', get_lang('GenerateSurveyAccessLink'), '', ICON_SIZE_SMALL),
api_get_path(WEB_CODE_PATH).'survey/generate_link.php?survey_id='.$survey_id.'&'.api_get_cidreq()
$actions[] = Display::url(
Display::return_icon('new_link.png', get_lang('GenerateSurveyAccessLink')),
$codePath.'survey/generate_link.php?'.http_build_query($params + ['survey_id' => $survey_id])
);
}
$return .= Display::url(
Display::return_icon('backup.png', get_lang('CopySurvey'), '', ICON_SIZE_SMALL),
'copy_survey.php?survey_id='.$survey_id.'&'.api_get_cidreq()
$actions[] = Display::url(
Display::return_icon('backup.png', get_lang('CopySurvey')),
$codePath.'survey/copy_survey.php?'.http_build_query($params + ['survey_id' => $survey_id])
);
$return .= Display::url(
Display::return_icon('copy.png', get_lang('DuplicateSurvey'), '', ICON_SIZE_SMALL),
'survey_list.php?action=copy_survey&survey_id='.$survey_id.'&'.api_get_cidreq()
$actions[] = Display::url(
Display::return_icon('copy.png', get_lang('DuplicateSurvey')),
$codePath.'survey/survey_list.php?'
.http_build_query($params + ['action' => 'copy_survey', 'survey_id' => $survey_id])
);
$return .= ' <a href="'.api_get_path(WEB_CODE_PATH).'survey/survey_list.php?'.api_get_cidreq()
.'&action=empty&survey_id='.$survey_id.'" onclick="javascript: if(!confirm(\''
.addslashes(api_htmlentities(get_lang("EmptySurvey").'?')).'\')) return false;">'
.Display::return_icon('clean.png', get_lang('EmptySurvey'), '', ICON_SIZE_SMALL)
.'</a>&nbsp;';
$warning = addslashes(api_htmlentities(get_lang("EmptySurvey").'?', ENT_QUOTES));
$actions[] = Display::url(
Display::return_icon('clean.png', get_lang('EmptySurvey')),
$codePath.'survey/survey_list.php'
.http_build_query($params + ['action' => 'empty', 'survey_id' => $survey_id]),
[
'onclick' => "javascript: if (!confirm('".$warning."')) return false;",
]
);
}
$return .= '<a href="'.api_get_path(WEB_CODE_PATH).'survey/preview.php?'.api_get_cidreq().'&survey_id='.$survey_id.'">'
.Display::return_icon('preview_view.png', get_lang('Preview'), '', ICON_SIZE_SMALL)
.'</a>&nbsp;';
$return .= '<a href="'.api_get_path(WEB_CODE_PATH).'survey/survey_invite.php?'.api_get_cidreq().'&survey_id='.$survey_id.'">'
.Display::return_icon('mail_send.png', get_lang('Publish'), '', ICON_SIZE_SMALL)
.'</a>&nbsp;';
$return .= $hideReportingButton ? '' : $reportingLink;
$actions[] = Display::url(
Display::return_icon('preview_view.png', get_lang('Preview')),
$codePath.'survey/preview.php?'.http_build_query($params + ['survey_id' => $survey_id])
);
$actions[] = Display::url(
Display::return_icon('mail_send.png', get_lang('Publish')),
$codePath.'survey/survey_invite.php?'.http_build_query($params + ['survey_id' => $survey_id])
);
$actions[] = $hideReportingButton ? null : $reportingLink;
if (api_is_allowed_to_edit() ||
api_is_element_in_the_session(TOOL_SURVEY, $survey_id)
) {
$return .= '<a href="'.api_get_path(WEB_CODE_PATH).'survey/survey_list.php?'.api_get_cidreq()
.'&action=delete&survey_id='.$survey_id.'" onclick="javascript: if(!confirm(\''
.addslashes(api_htmlentities(get_lang("DeleteSurvey").'?', ENT_QUOTES)).'\')) return false;">'
.Display::return_icon('delete.png', get_lang('Delete'), '', ICON_SIZE_SMALL)
.'</a>&nbsp;';
$warning = addslashes(api_htmlentities(get_lang("DeleteSurvey").'?', ENT_QUOTES));
$actions[] = Display::url(
Display::return_icon('delete.png', get_lang('Delete')),
$codePath.'survey/survey_list.php?'
.http_build_query($params + ['action' => 'delete', 'survey_id' => $survey_id]),
[
'onclick' => "javascript: if(!confirm('".$warning."')) return false;",
]
);
}
return $return;
return implode(PHP_EOL, $actions);
}
/**
@ -2920,16 +2939,29 @@ class SurveyUtil
public static function modify_filter_for_coach($survey_id)
{
$survey_id = (int) $survey_id;
$return = '<a href="'.api_get_path(WEB_CODE_PATH).'survey/preview.php?'.api_get_cidreq().'&survey_id='.$survey_id.'">'
.Display::return_icon('preview_view.png', get_lang('Preview'), '', ICON_SIZE_SMALL).'</a>&nbsp;';
$return .= '<a href="'.api_get_path(WEB_CODE_PATH).'survey/survey_invite.php?'.api_get_cidreq().'&survey_id='.$survey_id.'">'.
Display::return_icon('mail_send.png', get_lang('Publish'), '', ICON_SIZE_SMALL)
.'</a>&nbsp;';
$return .= '<a href="'.api_get_path(WEB_CODE_PATH).'survey/survey_list.php?'.api_get_cidreq().'&action=empty&survey_id='.$survey_id.'" onclick="javascript: if(!confirm(\''
.addslashes(api_htmlentities(get_lang("EmptySurvey").'?', ENT_QUOTES)).'\')) return false;">'
.Display::return_icon('clean.png', get_lang('EmptySurvey'), '', ICON_SIZE_SMALL).'</a>&nbsp;';
$actions = [];
$codePath = api_get_path(WEB_CODE_PATH);
$params = [];
parse_str(api_get_cidreq(), $params);
$actions[] = Display::url(
Display::return_icon('preview_view.png', get_lang('Preview')),
$codePath.'survey/preview.php?'.http_build_query($params + ['survey_id' => $survey_id])
);
$actions[] = Display::url(
Display::return_icon('mail_send.png', get_lang('Publish')),
$codePath.'survey/survey_invite.php?'.http_build_query($params + ['survey_id' => $survey_id])
);
$warning = addslashes(api_htmlentities(get_lang("EmptySurvey").'?', ENT_QUOTES));
$actions[] = Display::url(
Display::return_icon('clean.png', get_lang('EmptySurvey')),
$codePath.'survey/survey_list.php?'
.http_build_query($params + ['action' => 'empty', 'survey_id' => $survey_id]),
[
'onclick' => "javascript: if(!confirm('".$warning."')) return false;",
]
);
return $return;
return implode(PHP_EOL, $actions);
}
/**
@ -3076,7 +3108,7 @@ class SurveyUtil
survey.avail_till AS col6,
survey.invited AS col7,
survey.anonymous AS col8,
survey.survey_id AS col9,
survey.iid AS col9,
survey.session_id AS session_id,
survey.answered,
survey.invited
@ -3088,8 +3120,7 @@ class SurveyUtil
WHERE survey.c_id = $course_id
$search_restriction
$condition_session
GROUP BY
survey.survey_id, survey_question.question_id
GROUP BY survey.survey_id
ORDER BY col$column $direction
LIMIT $from,$number_of_items
";
@ -3724,4 +3755,35 @@ class SurveyUtil
return $response > 0;
}
/**
* Get the pending surveys for a user.
*
* @param int $userId
*
* @return array
*/
public static function getUserPendingInvitations($userId)
{
$now = api_get_utc_datetime(null, false, true);
$dql = "
SELECT s, si FROM ChamiloCourseBundle:CSurvey s
INNER JOIN ChamiloCourseBundle:CSurveyInvitation si
WITH (s.code = si.surveyCode AND s.cId = si.cId AND s.sessionId = si.sessionId )
WHERE
si.user = :user_id AND
s.availFrom <= :now AND
s.availTill >= :now AND
si.answered = 0
ORDER BY s.availTill ASC
";
$pendingSurveys = Database::getManager()
->createQuery($dql)
->setParameters(['user_id' => $userId, 'now' => $now->format('Y-m-d')])
->getResult();
return $pendingSurveys;
}
}

@ -49,7 +49,8 @@ echo '<div class="row">
echo '<div class="row"><div class="formw"><select name ="work_id" id="work_id">';
echo '<option value="0"'.(($row['colid'] == $rs->work_id) ? "selected" : "").'>'.get_lang('PleaseSelect').'</option>';
while ($row = Database::fetch_assoc($result_tasks)) {
echo '<option value="'.$row['colid'].'"'.(($row['colid'] == $rs->work_id) ? "selected" : "").'>'.$row['coltitle'].'</option>';
echo '<option value="'.$row['colid'].'"'.(($row['colid'] == $rs->work_id) ? "selected" : "").'>'.
$row['coltitle'].'</option>';
}
echo '</select></div><div>';
echo '<div class="row">
@ -58,7 +59,8 @@ echo '<div class="row">
echo '<div class="row"><div class="formw"><select name ="forum_id" id="forum_id">';
echo '<option value="0"'.(($row['colid'] == $rs->work_id) ? "forum_id" : "").'>'.get_lang('PleaseSelect').'</option>';
while ($row = Database::fetch_assoc($result_forum)) {
echo '<option value="'.$row['colid'].'"'.(($row['colid'] == $rs->forum_id) ? "selected" : "").'>'.$row['coltitle'].'</option>';
echo '<option value="'.$row['colid'].'"'.(($row['colid'] == $rs->forum_id) ? "selected" : "").'>'.
$row['coltitle'].'</option>';
}
echo '</select></div><div>';
echo '<div class="row">

@ -2,7 +2,7 @@
/* For licensing terms, see /license.txt */
/**
* @package chamilo.plugin.ticket
* @package chamilo.ticket
*/
$cidReset = true;

@ -8,7 +8,8 @@ require_once __DIR__.'/../inc/global.inc.php';
$this_section = SECTION_COURSES;
// Access restrictions.
$is_allowedToTrack = api_is_platform_admin() || api_is_allowed_to_create_course() || api_is_session_admin() || api_is_drh() || api_is_course_tutor();
$is_allowedToTrack = api_is_platform_admin() || api_is_allowed_to_create_course() ||
api_is_session_admin() || api_is_drh() || api_is_course_tutor();
if (!$is_allowedToTrack) {
api_not_allowed(true);

@ -14,7 +14,8 @@ if ($from == 'myspace') {
}
// Access restrictions.
$is_allowedToTrack = api_is_platform_admin() || api_is_allowed_to_create_course() || api_is_session_admin() || api_is_drh() || api_is_course_tutor();
$is_allowedToTrack = api_is_platform_admin() || api_is_allowed_to_create_course() ||
api_is_session_admin() || api_is_drh() || api_is_course_tutor();
if (!$is_allowedToTrack) {
api_not_allowed(true);
@ -108,16 +109,16 @@ $htmlHeadXtra[] = api_get_jqgrid_js();
$htmlHeadXtra[] = '
<script>
$(function() {
'.Display::grid_js(
'group_users',
$url,
$columns,
$column_model,
$extra_params,
[],
$action_links,
true
).'
'.Display::grid_js(
'group_users',
$url,
$columns,
$column_model,
$extra_params,
[],
$action_links,
true
).'
});
</script>';

@ -18,7 +18,8 @@ if ($from == 'myspace') {
}
// Access restrictions.
$is_allowedToTrack = api_is_platform_admin() || api_is_allowed_to_create_course() || api_is_session_admin() || api_is_drh() || api_is_course_tutor();
$is_allowedToTrack = api_is_platform_admin() || api_is_allowed_to_create_course() ||
api_is_session_admin() || api_is_drh() || api_is_course_tutor();
if (!$is_allowedToTrack) {
api_not_allowed(true);

@ -22,7 +22,8 @@ if ($from == 'myspace') {
}
// Access restrictions.
$is_allowedToTrack = api_is_platform_admin() || api_is_allowed_to_create_course() || api_is_session_admin() || api_is_drh() || api_is_course_tutor();
$is_allowedToTrack = api_is_platform_admin() || api_is_allowed_to_create_course() ||
api_is_session_admin() || api_is_drh() || api_is_course_tutor();
if (!$is_allowedToTrack) {
api_not_allowed();

@ -0,0 +1,77 @@
<?php
/* For licensing terms, see /license.txt */
require_once __DIR__.'/../inc/global.inc.php';
$allow = api_get_configuration_value('allow_user_message_tracking');
if (!$allow) {
api_not_allowed(true);
}
$allowUser = api_is_platform_admin() || api_is_drh();
if (!$allowUser) {
api_not_allowed(true);
}
$fromUserId = isset($_GET['from_user']) ? (int) $_GET['from_user'] : 0;
$toUserId = isset($_GET['to_user']) ? (int) $_GET['to_user'] : 0;
if (empty($fromUserId) || empty($toUserId)) {
api_not_allowed(true);
}
if (api_is_drh()) {
$isFollowed = UserManager::is_user_followed_by_drh($fromUserId, api_get_user_id());
if (!$isFollowed) {
api_not_allowed(true);
}
}
$usersData[$toUserId] = api_get_user_info($toUserId);
$usersData[$fromUserId] = api_get_user_info($fromUserId);
$messages = MessageManager::getAllMessagesBetweenStudents($toUserId, $fromUserId);
$content = Display::page_subheader2(sprintf(
get_lang('MessagesExchangeBetweenXAndY'),
$usersData[$toUserId]['complete_name'],
$usersData[$fromUserId]['complete_name']
));
$interbreadcrumb[] = [
'url' => api_get_path(WEB_CODE_PATH).'mySpace/student.php',
'name' => get_lang('MyStudents'),
];
$interbreadcrumb[] = [
'url' => api_get_path(WEB_CODE_PATH).'mySpace/myStudents.php?student='.$fromUserId,
'name' => get_lang('StudentDetails'),
];
$uniqueMessageList = [];
foreach ($messages as $message) {
$message['title'].
$subText = get_lang('From').': '.$usersData[$message['user_sender_id']]['complete_name'];
$title = empty($message['title']) ? get_lang('Untitled') : $message['title'];
$title = $title.' - '.$subText.'<span class="pull-right">'.Display::dateToStringAgoAndLongDate($message['send_date']).'</span>';
$messageId = $message['id'];
$hash = sha1($message['title'].$message['content'].$message['send_date']);
if (in_array($hash, $uniqueMessageList)) {
continue;
}
$content .= Display::panelCollapse(
$title,
$message['content'].'<br />'.Display::dateToStringAgoAndLongDate($message['send_date']),
'message-'.$message['id'],
null,
'message-'.$message['id'],
'collapse-'.$message['id'],
false
);
$uniqueMessageList[] = $hash;
}
$template = new Template(get_lang('MessageTracking'));
$template->assign('content', $content);
$template->display_one_col_template();

@ -15,23 +15,23 @@
$nameTools = get_lang('FileUpload');
$interbreadcrumb[] = ["url" => "../lp/lp_controller.php?action=list", "name" => get_lang(TOOL_DOCUMENT)];
Display::display_header($nameTools, "Doc");
//show the title
// Show the title
api_display_tool_title($nameTools.$add_group_to_title);
?>
<div id="dynamic_div" style="display:block;margin-left:40%;margin-top:10px;height:50px;">
</div>
<div id="upload_form_div" name="form_div" style="display:block;">
<form method="POST" action="upload.php" id="upload_form" enctype="multipart/form-data" onsubmit="javascript: myUpload.start('dynamic_div','progressbar_green.gif','<?php echo get_lang('Uploading', ''); ?>','upload_form_div');">
<input type="hidden" name="curdirpath" value="<?php echo $path; ?>">
<input type="hidden" name="tool" value="<?php echo $my_tool; ?>">
<input type="file" name="user_file">
<input type="submit" name="submit" value="Upload">
</form>
<form method="POST" action="upload.php" id="upload_form"
enctype="multipart/form-data"
onsubmit="javascript: myUpload.start('dynamic_div','progressbar_green.gif','<?php echo get_lang('Uploading', ''); ?>', 'upload_form_div');">
<input type="hidden" name="curdirpath" value="<?php echo $path; ?>">
<input type="hidden" name="tool" value="<?php echo $my_tool; ?>">
<input type="file" name="user_file">
<input type="submit" name="submit" value="Upload">
</form>
</div>
<br/>
<?php
/*
FOOTER
*/
Display::display_footer();

@ -87,46 +87,8 @@ if (api_get_setting('search_enabled') == 'true') {
if (api_is_platform_admin()) {
$form->addElement('checkbox', 'use_max_score', null, get_lang('UseMaxScore100'));
}
/* This is a special section that has to be enabled in specific cases
* PLEASE DO NOT REMOVE
$list = get_zip_files_in_garbage();
if (count($list)>0) {
$select_file_name = &$form->addElement(
'select',
'file_name',
get_lang('Or').' '.api_strtolower(get_lang('UploadLocalFileFromGarbageDir'))
);
foreach($list as $file){
$select_file_name->addOption($file, $file);
}
$form->addElement('submit', 'submit', get_lang('Download'));
} else {
$text_empty = &$form->addElement(
'text',
'empty',
get_lang('Or').' '.api_strtolower(get_lang('UploadLocalFileFromGarbageDir'))
);
$defaults["empty"] = get_lang('Empty');
$text_empty->freeze();
}*/
$form->addButtonUpload(get_lang('Upload'));
/*
TODO: check the pens plugin is enabled before using it
if (is_dir(api_get_path(PLUGIN_PATH)."/pens")) {
require_once api_get_path(PLUGIN_PATH)."/pens/chamilo_pens.php";
$list = ChamiloPens::findAll();
if (count($list) > 0) {
$select_pens = $form->addElement('select', 'pens_package', get_lang('Or').' '.get_lang('select a PENS package'));
foreach ($list as $package) {
$select_pens->addOption($package->getPackageName(), $package->getPackageName());
}
}
}
*/
// the default values for the form
$defaults = ['index_document' => 'checked="checked"', 'use_max_score' => 1];
$form->setDefaults($defaults);

@ -33,7 +33,13 @@ if (isset($_POST['convert'])) {
foreach ($values as $value) {
$value = trim($value);
if (!empty($value)) {
add_specific_field_value($specific_field['id'], api_get_course_id(), TOOL_LEARNPATH, $o_ppt->lp_id, $value);
add_specific_field_value(
$specific_field['id'],
api_get_course_id(),
TOOL_LEARNPATH,
$o_ppt->lp_id,
$value
);
}
}
}

@ -51,7 +51,13 @@ if (isset($_POST['convert'])) {
foreach ($values as $value) {
$value = trim($value);
if (!empty($value)) {
add_specific_field_value($specific_field['id'], api_get_course_id(), TOOL_LEARNPATH, $o_doc->lp_id, $value);
add_specific_field_value(
$specific_field['id'],
api_get_course_id(),
TOOL_LEARNPATH,
$o_doc->lp_id,
$value
);
}
}
}
@ -82,7 +88,8 @@ $interbreadcrumb[] = ["url" => "../lp/lp_controller.php?action=list", "name" =>
$nameTools = get_lang("WoogieConversionPowerPoint");
Display :: display_header($nameTools);
echo '<span style="color: #5577af; font-size: 16px; font-family: Arial; margin-left: 10px;">'.get_lang("WelcomeWoogieSubtitle").'</span><br>';
echo '<span style="color: #5577af; font-size: 16px; font-family: Arial; margin-left: 10px;">'.
get_lang("WelcomeWoogieSubtitle").'</span><br>';
$message = get_lang("WelcomeWoogieConverter");
echo '<br />';
$s_style = "border-width: 1px;
@ -112,11 +119,13 @@ $s_style_error = "border-width: 1px;
color: #000;";
echo '<div style="'.$s_style.'"><div style="float:left; margin-right:10px;">
<img src="'.Display::returnIconPath('message_normal.gif').'" alt="'.$alt_text.'" '.$attribute_list.' /></div><div style="margin-left: 43px">'.$message.'</div></div>';
<img src="'.Display::returnIconPath('message_normal.gif').'" alt="'.$alt_text.'" '.$attribute_list.' /></div>
<div style="margin-left: 43px">'.$message.'</div></div>';
if (!empty($errorMessage)) {
echo '<div style="'.$s_style_error.'"><div style="float:left; margin-right:10px;">
<img src="'.Display::returnIconPath('message_error.gif').'" alt="'.$alt_text.'" '.$attribute_list.' /></div><div style="margin-left: 43px">'.$errorMessage.'</div></div>';
<img src="'.Display::returnIconPath('message_error.gif').'" alt="'.$alt_text.'" '.$attribute_list.' /></div>
<div style="margin-left: 43px">'.$errorMessage.'</div></div>';
}
$form = new FormValidator('update_course', 'POST', '', '', 'style="margin: 0;"');

@ -216,14 +216,12 @@ if ($allowTutors == 'true') {
}
$xajax->processRequests();
$htmlHeadXtra[] = $xajax->getJavascript('../inc/lib/xajax/');
$htmlHeadXtra[] = '<script>
function add_user_to_session (code, content) {
document.getElementById("user_to_add").value = "";
document.getElementById("ajax_list_users_single").innerHTML = "";
destination = document.getElementById("destination_users");
for (i=0;i<destination.length;i++) {
if(destination.options[i].text == content) {
return false;
@ -260,9 +258,7 @@ if ($allowTutors == 'true') {
$("#user_with_any_session_id").attr("checked", false);
xajax_search_users(val,"multiple");
}
</script>';
$form_sent = 0;
$firstLetterUser = $firstLetterSession = '';
$UserList = $SessionList = [];
@ -287,9 +283,7 @@ if ($allowTutors == 'true') {
$session_info = SessionManager::fetch($id_session);
Display::display_header($tool_name);
$nosessionUsersList = $sessionUsersList = [];
$ajax_search = $add_type === 'unique' ? true : false;
$order_clause = api_sort_by_first_name() ? ' ORDER BY firstname, lastname, username' : ' ORDER BY lastname, firstname, username';
@ -472,18 +466,21 @@ if ($allowTutors == 'true') {
}
if ($add_type === 'multiple') {
$link_add_type_unique = '<a href="'.api_get_self().'?id_session='.$id_session.'&add='.Security::remove_XSS($_GET['add']).'&add_type=unique">'.Display::return_icon('single.gif').get_lang('SessionAddTypeUnique').'</a>';
$link_add_type_unique = '<a href="'.api_get_self().'?id_session='.$id_session.'&add='.Security::remove_XSS($_GET['add']).'&add_type=unique">'.
Display::return_icon('single.gif').get_lang('SessionAddTypeUnique').'</a>';
$link_add_type_multiple = Display::return_icon('multiple.gif').get_lang('SessionAddTypeMultiple');
} else {
$link_add_type_unique = Display::return_icon('single.gif').get_lang('SessionAddTypeUnique');
$link_add_type_multiple = '<a href="'.api_get_self().'?id_session='.$id_session.'&add='.Security::remove_XSS($_GET['add']).'&add_type=multiple">'.Display::return_icon('multiple.gif').get_lang('SessionAddTypeMultiple').'</a>';
$link_add_type_multiple = '<a href="'.api_get_self().'?id_session='.$id_session.'&add='.Security::remove_XSS($_GET['add']).'&add_type=multiple">'.
Display::return_icon('multiple.gif').get_lang('SessionAddTypeMultiple').'</a>';
}
$link_add_group = '<a href="usergroups.php">'.
Display::return_icon('multiple.gif', get_lang('RegistrationByUsersGroups')).get_lang('RegistrationByUsersGroups').'</a>'; ?>
<div class="actions">
<?php echo $link_add_type_unique; ?>&nbsp;|&nbsp;<?php echo $link_add_type_multiple; ?>&nbsp;|&nbsp;<?php echo $link_add_group; ?>
</div>
<form name="formulaire" method="post" action="<?php echo api_get_self(); ?>?page=<?php echo $page; ?>&id_session=<?php echo $id_session; ?><?php if (!empty($_GET['add'])) {
<form name="formulaire" method="post"
action="<?php echo api_get_self(); ?>?page=<?php echo $page; ?>&id_session=<?php echo $id_session; ?><?php if (!empty($_GET['add'])) {
echo '&add=true';
} ?>" style="margin:0px;" <?php if ($ajax_search) {
echo ' onsubmit="valide();"';
@ -522,7 +519,6 @@ if ($allowTutors == 'true') {
<div class="span5">
<div class="multiple_select_header">
<b><?php echo get_lang('UserListInPlatform'); ?> :</b>
<?php if ($add_type == 'multiple') {
?>
<?php echo get_lang('FirstLetterUser'); ?> :
@ -652,7 +648,6 @@ if ($allowTutors == 'true') {
document.forms.formulaire.submit();
}
function loadUsersInSelect(select)
{
var xhr_object = null;

@ -46,8 +46,8 @@ if (!empty($usergroup_list)) {
}
}
Display :: display_header($tool_name, 'Classes');
Display::display_header($tool_name, 'Classes');
echo $content;
Display :: display_footer();
Display::display_footer();

@ -238,8 +238,7 @@ if ($allowTutors === 'true') {
$result = Database::query($sql);
$courses = Database::store_result($result);
foreach ($courses as $course) {
//select the number of users
// Select the number of users
$sql = "SELECT count(*) FROM $tbl_session_rel_user sru, $tbl_session_rel_course_rel_user srcru
WHERE
srcru.user_id = sru.user_id AND

@ -72,8 +72,13 @@ if (!empty($items)) {
$usersAdded[] = $myUserId;
$userInfo = api_get_user_info($myUserId);
$url = api_get_path(WEB_CODE_PATH).'work/add_user.php?action=delete&id='.$workId.'&user_id='.$myUserId;
$link = Display::url('<em class="fa fa-trash"></em> '.get_lang('Delete'), $url, ['class' => 'btn btn-danger btn-sm']);
echo '<li class="list-group-item">'.$userInfo['complete_name_with_username'].'<div class="pull-right">'.$link.'</div></li>';
$link = Display::url(
'<em class="fa fa-trash"></em> '.get_lang('Delete'),
$url,
['class' => 'btn btn-danger btn-sm']
);
echo '<li class="list-group-item">'.
$userInfo['complete_name_with_username'].'<div class="pull-right">'.$link.'</div></li>';
}
echo '</ul>';
}
@ -105,7 +110,11 @@ if (!empty($userToAddList)) {
foreach ($userToAddList as $user) {
$userName = api_get_person_name($user['firstname'], $user['lastname']).' ('.$user['username'].') ';
$url = api_get_path(WEB_CODE_PATH).'work/add_user.php?action=add&id='.$workId.'&user_id='.$user['user_id'];
$link = Display::url('<em class="fa fa-plus"></em> '.get_lang('Add'), $url, ['class' => 'btn btn-primary btn-sm']);
$link = Display::url(
'<em class="fa fa-plus"></em> '.get_lang('Add'),
$url,
['class' => 'btn btn-primary btn-sm']
);
echo '<li class="list-group-item">'.$userName.'<div class="pull-right"> '.$link.'</div></li>';
}
echo '</ul>';

@ -18,17 +18,16 @@ $this_section = SECTION_COURSES;
// Course protection
api_protect_course_script(true);
$id = intval($_GET['id']);
$id = isset($_GET['id']) ? (int) $_GET['id'] : 0;
$courseInfo = api_get_course_info();
if (empty($courseInfo)) {
if (empty($courseInfo) || empty($id)) {
api_not_allowed(true);
}
$correction = isset($_REQUEST['correction']) ? true : false;
$result = downloadFile($id, $courseInfo, $correction);
if ($result == false) {
if ($result === false) {
api_not_allowed(true);
}

@ -8,21 +8,26 @@
*
* @package chamilo.work
*/
$work_id = $_GET['id'];
require_once __DIR__.'/../inc/global.inc.php';
api_protect_course_script(true);
$workId = isset($_GET['id']) ? (int) $_GET['id'] : 0;
$current_course_tool = TOOL_STUDENTPUBLICATION;
$_course = api_get_course_info();
// Protection
api_protect_course_script(true);
if (empty($_course)) {
api_not_allowed();
}
require_once 'work.lib.php';
$work_data = get_work_data_by_id($work_id);
$work_data = get_work_data_by_id($workId);
$groupId = api_get_group_id();
if (empty($work_data)) {
exit;
api_not_allowed();
}
// Prevent some stuff.
@ -87,7 +92,7 @@ if (api_is_allowed_to_edit() || api_is_coach()) {
props.tool = 'work' AND
props.c_id = $course_id AND
work.c_id = $course_id AND
work.parent_id = $work_id AND
work.parent_id = $workId AND
work.filetype = 'file' AND
props.visibility <> '2' AND
work.active IN (0, 1) AND
@ -96,9 +101,8 @@ if (api_is_allowed_to_edit() || api_is_coach()) {
";
} else {
$courseInfo = api_get_course_info();
protectWork($courseInfo, $work_id);
$userCondition = null;
protectWork($courseInfo, $workId);
$userCondition = '';
// All users
if ($courseInfo['show_score'] == 0) {
@ -129,7 +133,7 @@ if (api_is_allowed_to_edit() || api_is_coach()) {
props.tool = 'work' AND
work.accepted = 1 AND
work.active = 1 AND
work.parent_id = $work_id AND
work.parent_id = $workId AND
work.filetype = 'file' AND
props.visibility = '1' AND
work.post_group_id = $groupIid
@ -140,7 +144,7 @@ $query = Database::query($sql);
//add tem to the zip file
while ($not_deleted_file = Database::fetch_assoc($query)) {
$user_info = api_get_user_info($not_deleted_file['insert_user_id']);
$userInfo = api_get_user_info($not_deleted_file['insert_user_id']);
$insert_date = api_get_local_time($not_deleted_file['sent_date']);
$insert_date = str_replace([':', '-', ' '], '_', $insert_date);
@ -150,8 +154,8 @@ while ($not_deleted_file = Database::fetch_assoc($query)) {
$title = $not_deleted_file['filename'];
}
}
$filename = $insert_date.'_'.$user_info['username'].'_'.$title;
$filename = $insert_date.'_'.$userInfo['username'].'_'.$title;
$filename = api_replace_dangerous_char($filename);
// File exists
if (file_exists($sys_course_path.$_course['path'].'/'.$not_deleted_file['url']) &&
!empty($not_deleted_file['url'])
@ -198,8 +202,7 @@ if (!empty($files)) {
exit;
}
/* Extra function (only used here) */
/* Extra function (only used here) */
function my_pre_add_callback($p_event, &$p_header)
{
global $files;

@ -13,7 +13,7 @@ require_once 'work.lib.php';
$this_section = SECTION_COURSES;
$workId = isset($_REQUEST['id']) ? intval($_REQUEST['id']) : null;
$workId = isset($_REQUEST['id']) ? (int) $_REQUEST['id'] : 0;
$is_allowed_to_edit = api_is_allowed_to_edit();
$course_id = api_get_course_int_id();
@ -29,9 +29,12 @@ if (empty($workId)) {
}
protectWork($courseInfo, $workId);
$workInfo = get_work_data_by_id($workId);
if (empty($workInfo)) {
api_not_allowed(true);
}
$student_can_edit_in_session = api_is_allowed_to_session_edit(false, true);
$homework = get_work_assignment_by_id($workInfo['id']);
@ -102,7 +105,7 @@ if ($form->validate()) {
$destinationDir = api_get_path(SYS_ARCHIVE_PATH).$folder;
mkdir($destinationDir, api_get_permissions_for_new_directories(), true);
/* Uncompress zip file*/
// Uncompress zip file
// We extract using a callback function that "cleans" the path
$result = $zip->extract(
PCLZIP_OPT_PATH,

@ -47,12 +47,12 @@ function displayWorkActionLinks($id, $action, $isTutor)
if (empty($id)) {
$output .= '<a href="'.api_get_self().'?'.api_get_cidreq().'&action=create_dir">';
$output .= Display::return_icon(
'new_work.png',
get_lang('CreateAssignment'),
'',
ICON_SIZE_MEDIUM
).
'</a>';
'new_work.png',
get_lang('CreateAssignment'),
'',
ICON_SIZE_MEDIUM
);
$output .= '</a>';
}
}
@ -77,18 +77,6 @@ function displayWorkActionLinks($id, $action, $isTutor)
'</a>';
}
if (api_is_allowed_to_edit(null, true) &&
$origin != 'learnpath' &&
api_is_allowed_to_session_edit(false, true)
) {
// Delete all files
if (api_get_setting('permanently_remove_deleted_files') == 'true') {
$message = get_lang('ConfirmYourChoiceDeleteAllfiles');
} else {
$message = get_lang('ConfirmYourChoice');
}
}
if ($output != '') {
echo '<div class="actions">';
echo $output;
@ -108,9 +96,8 @@ function displayWorkActionLinks($id, $action, $isTutor)
*/
function settingsForm($defaults)
{
$is_allowed_to_edit = api_is_allowed_to_edit(null, true);
if (!$is_allowed_to_edit) {
$allowed = api_is_allowed_to_edit(null, true);
if (!$allowed) {
return;
}
@ -150,8 +137,8 @@ function get_work_data_by_path($path, $courseId = 0)
$courseId = api_get_course_int_id();
}
$work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
$sql = "SELECT * FROM ".$work_table."
$table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
$sql = "SELECT * FROM $table
WHERE url = '$path' AND c_id = $courseId ";
$result = Database::query($sql);
$return = [];
@ -178,7 +165,7 @@ function get_work_data_by_id($id, $courseId = 0, $sessionId = 0)
}
$table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
$sessionCondition = null;
$sessionCondition = '';
if (!empty($sessionId)) {
$sessionCondition = api_get_session_condition($sessionId, true);
}
@ -257,15 +244,13 @@ function get_work_count_by_student($user_id, $work_id)
*
* @return array
*/
function get_work_assignment_by_id($id, $courseId = null)
function get_work_assignment_by_id($id, $courseId = 0)
{
$courseId = intval($courseId);
if (empty($courseId)) {
$courseId = api_get_course_int_id();
} else {
$courseId = intval($courseId);
}
$id = intval($id);
$table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
$sql = "SELECT * FROM $table
WHERE c_id = $courseId AND publication_id = $id";
@ -299,11 +284,12 @@ function getWorkList($id, $my_folder_data, $add_in_where_query = null, $course_i
$groupIid = 0;
if ($group_id) {
$groupInfo = GroupManager::get_group_properties($group_id);
$groupIid = $groupInfo['iid'];
if ($groupInfo) {
$groupIid = $groupInfo['iid'];
}
}
$is_allowed_to_edit = api_is_allowed_to_edit(null, true);
$linkInfo = GradebookUtils::isResourceInCourseGradebook(
api_get_course_id(),
3,
@ -326,7 +312,6 @@ function getWorkList($id, $my_folder_data, $add_in_where_query = null, $course_i
}
$contains_file_query = '';
// Get list from database
if ($is_allowed_to_edit) {
$active_condition = ' active IN (0, 1)';
@ -604,9 +589,6 @@ function showTeacherWorkGrid()
['name' => 'amount', 'index' => 'amount', 'width' => '110', 'align' => 'center', 'sortable' => 'false'],
['name' => 'actions', 'index' => 'actions', 'width' => '110', 'align' => 'left', 'sortable' => 'false'],
];
$token = null;
$url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_work_teacher&'.api_get_cidreq();
$deleteUrl = api_get_path(WEB_AJAX_PATH).'work.ajax.php?a=delete_work&'.api_get_cidreq();
@ -659,7 +641,8 @@ function showTeacherWorkGrid()
function build_work_directory_selector($folders, $curdirpath, $group_dir = '')
{
$form = '<form name="selector" action="'.api_get_self().'?'.api_get_cidreq().'" method="POST">';
$form .= get_lang('CurrentDirectory').' <select name="curdirpath" onchange="javascript: document.selector.submit();">';
$form .= get_lang('CurrentDirectory').'
<select name="curdirpath" onchange="javascript: document.selector.submit();">';
//group documents cannot be uploaded in the root
if ($group_dir == '') {
$form .= '<option value="/">/ ('.get_lang('Root').')</option>';
@ -686,7 +669,7 @@ function build_work_directory_selector($folders, $curdirpath, $group_dir = '')
}
/**
* Builds the form thats enables the user to
* Builds the form that enables the user to
* move a document from one directory to another
* This function has been copied from the document/document.inc.php library.
*
@ -718,19 +701,18 @@ function build_work_move_to_selector($folders, $curdirpath, $move_file, $group_d
$form->addHidden('item_id', $move_file);
$form->addHidden('action', 'move_to');
//group documents cannot be uploaded in the root
// Group documents cannot be uploaded in the root
if ($group_dir == '') {
if ($curdirpath != '/') {
//$form .= '<option value="0">/ ('.get_lang('Root').')</option>';
}
if (is_array($folders)) {
foreach ($folders as $fid => $folder) {
//you cannot move a file to:
//1. current directory
//2. inside the folder you want to move
//3. inside a subfolder of the folder you want to move
if (($curdirpath != $folder) && ($folder != $move_file) && (substr($folder, 0, strlen($move_file) + 1) != $move_file.'/')) {
//$form .= '<option value="'.$fid.'">'.$folder.'</option>';
if (($curdirpath != $folder) &&
($folder != $move_file) &&
(substr($folder, 0, strlen($move_file) + 1) != $move_file.'/')
) {
$options[$fid] = $folder;
}
}
@ -740,7 +722,9 @@ function build_work_move_to_selector($folders, $curdirpath, $move_file, $group_d
$form .= '<option value="0">/ ('.get_lang('Root').')</option>';
}
foreach ($folders as $fid => $folder) {
if (($curdirpath != $folder) && ($folder != $move_file) && (substr($folder, 0, strlen($move_file) + 1) != $move_file.'/')) {
if (($curdirpath != $folder) && ($folder != $move_file) &&
(substr($folder, 0, strlen($move_file) + 1) != $move_file.'/')
) {
//cannot copy dir into his own subdir
$display_folder = substr($folder, strlen($group_dir));
$display_folder = ($display_folder == '') ? '/ ('.get_lang('Root').')' : $display_folder;
@ -812,18 +796,15 @@ function deleteDirWork($id)
$base_work_dir = api_get_path(SYS_COURSE_PATH).$_course['path'].'/work';
$work_data_url = $base_work_dir.$work_data['url'];
$check = Security::check_abs_path($work_data_url.'/', $base_work_dir.'/');
$table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
$TSTDPUBASG = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
$t_agenda = Database::get_course_table(TABLE_AGENDA);
$course_id = api_get_course_int_id();
$sessionId = api_get_session_id();
if (!empty($work_data['url'])) {
if ($check) {
$consideredWorkingTime = api_get_configuration_value('considered_working_time');
if (!empty($consideredWorkingTime)) {
$fieldValue = new ExtraFieldValue('work');
$resultExtra = $fieldValue->getAllValuesForAnItem(
@ -832,7 +813,6 @@ function deleteDirWork($id)
);
$workingTime = null;
foreach ($resultExtra as $field) {
$field = $field['value'];
if ($consideredWorkingTime == $field->getField()->getVariable()) {
@ -843,7 +823,6 @@ function deleteDirWork($id)
}
$courseUsers = CourseManager::get_user_list_from_course_code($_course['code'], $sessionId);
if (!empty($workingTime)) {
foreach ($courseUsers as $user) {
$userWorks = get_work_user_list(
@ -862,7 +841,6 @@ function deleteDirWork($id)
if (count($userWorks) != 1) {
continue;
}
Event::eventRemoveVirtualCourseTime($course_id, $user['user_id'], $sessionId, $workingTime);
}
}
@ -919,14 +897,14 @@ function deleteDirWork($id)
$sessionId
);
$link_info = GradebookUtils::isResourceInCourseGradebook(
$linkInfo = GradebookUtils::isResourceInCourseGradebook(
api_get_course_id(),
3,
$id,
api_get_session_id()
);
$link_id = $link_info['id'];
if ($link_info !== false) {
$link_id = $linkInfo['id'];
if ($linkInfo !== false) {
GradebookUtils::remove_resource_from_course_gradebook($link_id);
}
@ -1031,151 +1009,6 @@ function updateDirName($work_data, $newPath)
}
}
/**
* Return an array with all the folder's ids that are in the given path.
*
* @param string Path of the directory
*
* @return array The list of ids of all the directories in the path
*
* @author Julio Montoya
*
* @version April 2008
*/
function get_parent_directories($id)
{
$course_id = api_get_course_int_id();
$em = Database::getManager();
$directories = $em
->getRepository('ChamiloCourseBundle:CStudentPublication')
->findBy([
'cId' => $course_id,
'parentId' => $id,
]);
$list_id = [];
foreach ($directories as $directory) {
$list_id[] = $directory->getId();
}
return $list_id;
}
/**
* Transform an all directory structure (only directories) in an array.
*
* @param string path of the directory
*
* @return array the directory structure into an array
*
* @author Julio Montoya
*
* @version April 2008
*/
function directory_to_array($directory)
{
$array_items = [];
if ($handle = @opendir($directory)) {
while (false !== ($file = readdir($handle))) {
if ($file != '.' && $file != '..') {
if (is_dir($directory.'/'.$file)) {
$array_items = array_merge($array_items, directory_to_array($directory.'/'.$file));
$file = $directory.'/'.$file;
$array_items[] = preg_replace("/\/\//si", '/', $file);
}
}
}
closedir($handle);
}
return $array_items;
}
/**
* Insert into the DB of the course all the directories.
*
* @param string $base_work_dir path of the /work directory of the course
*
* @return mixed Int -1 on error, sql query result on success
*
* @author Julio Montoya
*
* @version April 2008
*/
function insert_all_directory_in_course_table($base_work_dir)
{
$dir_to_array = directory_to_array($base_work_dir, true);
$only_dir = [];
for ($i = 0; $i < count($dir_to_array); $i++) {
$only_dir[] = substr($dir_to_array[$i], strlen($base_work_dir), strlen($dir_to_array[$i]));
}
$course_id = api_get_course_int_id();
$group_id = api_get_group_id();
$work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
$groupIid = 0;
if ($group_id) {
$groupInfo = GroupManager::get_group_properties($group_id);
$groupIid = $groupInfo['iid'];
}
for ($i = 0; $i < count($only_dir); $i++) {
$url = $only_dir[$i];
$params = [
'c_id' => $course_id,
'url' => $url,
'title' => '',
'description' => '',
'author' => '',
'active' => '1',
'accepted' => '1',
'filetype' => 'folder',
'post_group_id' => $groupIid,
];
Database::insert($work_table, $params);
}
}
/**
* This function displays the number of files contained in a directory.
*
* @param string the path of the directory
* @param bool true if we want the total quantity of files
* include in others child directories, false only files in the directory
*
* @return array the first element is an integer with the number of files
* in the folder, the second element is the number of directories
*
* @author Julio Montoya
*
* @version April 2008
*/
function count_dir($path_dir, $recurse)
{
$count = 0;
$count_dir = 0;
$d = dir($path_dir);
while ($entry = $d->Read()) {
if (!(($entry == '..') || ($entry == '.'))) {
if (is_dir($path_dir.'/'.$entry)) {
$count_dir++;
if ($recurse) {
$count += count_dir($path_dir.'/'.$entry, $recurse);
}
} else {
$count++;
}
}
}
$return_array = [];
$return_array[] = $count;
$return_array[] = $count_dir;
return $return_array;
}
/**
* returns all the javascript that is required for easily
* validation when you create a work
@ -1183,11 +1016,9 @@ function count_dir($path_dir, $recurse)
*/
function to_javascript_work()
{
$js = '<script>
$js = '<script>
function updateDocumentTitle(value) {
var temp = value.indexOf("/");
var temp = value.indexOf("/");
//linux path
if(temp != -1){
temp=value.split("/");
@ -1209,67 +1040,15 @@ function to_javascript_work()
}
document.getElementById("file_upload").value = baseFilename;
document.getElementById("file_extension").value = fileExtension;
document.getElementById("file_extension").value = fileExtension;
$("#contains_file_id").attr("value", 1);
}
function checkDate(month, day, year) {
var monthLength =
new Array(31,28,31,30,31,30,31,31,30,31,30,31);
if (!day || !month || !year)
return false;
// check for bisestile year
if (year/4 == parseInt(year/4))
monthLength[1] = 29;
if (month < 1 || month > 12)
return false;
if (day > monthLength[month-1])
return false;
return true;
}
function mktime() {
var no, ma = 0, mb = 0, i = 0, d = new Date(), argv = arguments, argc = argv.length;
d.setHours(0,0,0); d.setDate(1); d.setMonth(1); d.setYear(1972);
var dateManip = {
0: function(tt){ return d.setHours(tt); },
1: function(tt){ return d.setMinutes(tt); },
2: function(tt){ set = d.setSeconds(tt); mb = d.getDate() - 1; return set; },
3: function(tt){ set = d.setMonth(parseInt(tt)-1); ma = d.getFullYear() - 1972; return set; },
4: function(tt){ return d.setDate(tt+mb); },
5: function(tt){ return d.setYear(tt+ma); }
};
for( i = 0; i < argc; i++ ){
no = parseInt(argv[i]*1);
if (isNaN(no)) {
return false;
} else {
// arg is number, lets manipulate date object
if(!dateManip[i](no)){
// failed
return false;
}
}
}
return Math.floor(d.getTime()/1000);
}
function setFocus() {
$("#work_title").focus();
}
$(document).ready(function() {
setFocus();
var checked = $("#expiry_date").attr("checked");
if (checked) {
$("#option2").show();
@ -1306,7 +1085,8 @@ function to_javascript_work()
*
* @return true if is found / false if not found
*/
// TODO: The name of this function does not fit with the kind of information it returns. Maybe check_work_id() or is_work_id()?
// TODO: The name of this function does not fit with the kind of information it returns.
// Maybe check_work_id() or is_work_id()?
function get_work_id($path)
{
$TBL_STUDENT_PUBLICATION = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
@ -2084,8 +1864,8 @@ function get_work_user_list(
if (!empty($work_data)) {
if (!empty($group_id)) {
// set to select only messages posted by the user's group
$extra_conditions = " work.post_group_id = '".intval($groupIid)."' ";
// set to select only messages posted by the user's group
} else {
$extra_conditions = " (work.post_group_id = '0' OR work.post_group_id is NULL) ";
}
@ -2270,13 +2050,12 @@ function get_work_user_list(
$work['type'] = DocumentManager::build_document_icon_tag('file', $work['url']);
// File name.
$link_to_download = null;
$linkToDownload = '';
// If URL is present then there's a file to download keep BC.
if ($work['contains_file'] || !empty($work['url'])) {
$link_to_download = '<a href="'.$url.'download.php?id='.$item_id.'&'.api_get_cidreq().'">'.$saveIcon.'</a> ';
$linkToDownload = '<a href="'.$url.'download.php?id='.$item_id.'&'.api_get_cidreq().'">'.$saveIcon.'</a> ';
}
$send_to = '';
$feedback = '';
$count = getWorkCommentCount($item_id, $course_info);
if (!is_null($count) && !empty($count)) {
@ -2309,17 +2088,22 @@ function get_work_user_list(
$date = date_to_str_ago($work['sent_date']).' '.$work_date;
$work['formatted_date'] = $work_date.' '.$add_string;
$work['sent_date_from_db'] = $work['sent_date'];
$work['sent_date'] = '<div class="work-date" title="'.$date.'">'.$add_string.' '.Display::dateToStringAgoAndLongDate($work['sent_date']).'</div>';
$work['sent_date'] = '<div class="work-date" title="'.$date.'">'.
$add_string.' '.Display::dateToStringAgoAndLongDate($work['sent_date']).'</div>';
$work['status'] = $hasCorrection;
$work['has_correction'] = $hasCorrection;
// Actions.
$action = '';
if (api_is_allowed_to_edit()) {
$action .= '<a href="'.$url.'view.php?'.api_get_cidreq().'&id='.$item_id.'" title="'.get_lang('View').'">'.$rateIcon.'</a> ';
$action .= '<a
href="'.$url.'view.php?'.api_get_cidreq().'&id='.$item_id.'"
title="'.get_lang('View').'">'.$rateIcon.'</a> ';
if ($unoconv && empty($work['contains_file'])) {
$action .= '<a href="'.$url.'work_list_all.php?'.api_get_cidreq().'&id='.$work_id.'&action=export_to_doc&item_id='.$item_id.'" title="'.get_lang('ExportToDoc').'" >'.
$action .= '<a f
href="'.$url.'work_list_all.php?'.api_get_cidreq().'&id='.$work_id.'&action=export_to_doc&item_id='.$item_id.'"
title="'.get_lang('ExportToDoc').'" >'.
Display::return_icon('export_doc.png', get_lang('ExportToDoc'), [], ICON_SIZE_SMALL).'</a> ';
}
@ -2379,7 +2163,12 @@ function get_work_user_list(
if ($locked) {
if ($qualification_exists) {
$action .= Display::return_icon('edit_na.png', get_lang('CorrectAndRate'), [], ICON_SIZE_SMALL);
$action .= Display::return_icon(
'edit_na.png',
get_lang('CorrectAndRate'),
[],
ICON_SIZE_SMALL
);
} else {
$action .= Display::return_icon('edit_na.png', get_lang('Comment'), [], ICON_SIZE_SMALL);
}
@ -2445,7 +2234,7 @@ function get_work_user_list(
$qualificator_id = Display::label(get_lang('Revised'), 'success');
}
$work['qualificator_id'] = $qualificator_id.' '.$hasCorrection;
$work['actions'] = '<div class="work-action">'.$send_to.$link_to_download.$action.'</div>';
$work['actions'] = '<div class="work-action">'.$linkToDownload.$action.'</div>';
$work['correction'] = $correction;
$works[] = $work;
}
@ -2599,9 +2388,9 @@ function sendEmailToStudentsOnHomeworkCreation($workId, $courseId, $sessionId =
*/
function is_work_exist_by_url($url)
{
$work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
$table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
$url = Database::escape_string($url);
$sql = "SELECT id FROM $work_table WHERE url='$url'";
$sql = "SELECT id FROM $table WHERE url='$url'";
$result = Database::query($sql);
if (Database::num_rows($result) > 0) {
$row = Database::fetch_row($result);
@ -2779,8 +2568,6 @@ function get_list_users_without_publication($task_id, $studentId = 0)
* @param int task id
* @param int $studentId
*
* @return array
*
* @author cvargas carlos.vargas@beeznest.com cfasanando, christian.fasanado@beeznest.com
* @author Julio Montoya <gugli100@gmail.com> Fixes
*/
@ -2878,7 +2665,9 @@ function getDocumentToWorkPerUser($documentId, $workId, $courseId, $sessionId, $
$active = intval($active);
$sessionCondition = api_get_session_condition($sessionId);
$sql = "SELECT w.* FROM $work w INNER JOIN $workRel rel ON (w.parent_id = rel.work_id)
$sql = "SELECT w.* FROM $work w
INNER JOIN $workRel rel
ON (w.parent_id = rel.work_id)
WHERE
w.document_id = $documentId AND
w.parent_id = $workId AND
@ -3387,6 +3176,7 @@ function getLastWorkStudentFromParent(
/**
* Get last work information from parent.
*
* @param int $userId
* @param array $parentInfo
* @param array $courseInfo
* @param int $sessionId
@ -3622,6 +3412,10 @@ function addWorkComment($courseInfo, $userId, $parentWork, $work, $data)
$subject = sprintf(get_lang('ThereIsANewWorkFeedback'), $parentWork['title']);
$content = sprintf(get_lang('ThereIsANewWorkFeedbackInWorkXHere'), $work['title'], $url);
if (!empty($data['comment'])) {
$content .= '<br /><b>'.get_lang('Comment').':</b><br />'.$data['comment'];
}
if (!empty($userIdListToSend)) {
foreach ($userIdListToSend as $userIdToSend) {
MessageManager::send_message_simple(
@ -3696,7 +3490,7 @@ function getWorkCommentForm($work, $workParent)
}
}
Skill::addSkillsToUserForm($form, ITEM_TYPE_STUDENT_PUBLICATION, $workParent['id'], $work['user_id']);
Skill::addSkillsToUserForm($form, ITEM_TYPE_STUDENT_PUBLICATION, $workParent['id'], $work['user_id'], $work['id']);
$form->addHtmlEditor('comment', get_lang('Comment'), false);
$form->addFile('attachment', get_lang('Attachment'));
$form->addElement('hidden', 'id', $work['id']);
@ -3860,14 +3654,14 @@ function uploadWork($my_folder_data, $_course, $isCorrection = false, $workInfo
if (empty($filesize)) {
return [
'error' => Display:: return_message(
'error' => Display::return_message(
get_lang('UplUploadFailedSizeIsZero'),
'error'
),
];
} elseif (!filter_extension($new_file_name)) {
return [
'error' => Display:: return_message(
'error' => Display::return_message(
get_lang('UplUnableToSaveFileFilteredExtension'),
'error'
),
@ -3880,7 +3674,7 @@ function uploadWork($my_folder_data, $_course, $isCorrection = false, $workInfo
if ($total_size > $course_max_space) {
return [
'error' => Display :: return_message(get_lang('NoSpace'), 'error'),
'error' => Display::return_message(get_lang('NoSpace'), 'error'),
];
}
@ -3912,7 +3706,6 @@ function uploadWork($my_folder_data, $_course, $isCorrection = false, $workInfo
];
}
$url = null;
if ($result) {
$url = 'work/'.$curdirpath.'/'.$new_file_name;
} else {
@ -3923,7 +3716,7 @@ function uploadWork($my_folder_data, $_course, $isCorrection = false, $workInfo
'url' => $url,
'filename' => $filename,
'filesize' => $filesize,
'error' => null,
'error' => '',
];
}
@ -3987,13 +3780,6 @@ function sendAlertToUsers($workId, $courseInfo, $session_id)
}
if ($send) {
$senderEmail = api_get_setting('emailAdministrator');
$senderName = api_get_person_name(
api_get_setting('administratorName'),
api_get_setting('administratorSurname'),
null,
PERSON_NAME_EMAIL_ADDRESS
);
$subject = "[".api_get_setting('siteName')."] ".get_lang('SendMailBody')."\n ".get_lang('CourseName').": ".$courseInfo['name']." ";
foreach ($user_list as $user_data) {
$to_user_id = $user_data['user_id'];
@ -4003,7 +3789,6 @@ function sendAlertToUsers($workId, $courseInfo, $session_id)
$message .= get_lang('DateSent')." : ".api_format_date(api_get_local_time())."\n";
$url = api_get_path(WEB_CODE_PATH)."work/work.php?cidReq=".$courseInfo['code']."&id_session=".$session_id."&id=".$workData['id'];
$message .= get_lang('WorkName')." : ".$workData['title']."\n\n".'<a href="'.$url.'">'.get_lang('DownloadLink')."</a>\n";
//$message .= $url;
MessageManager::send_message_simple(
$to_user_id,
$subject,
@ -4014,18 +3799,6 @@ function sendAlertToUsers($workId, $courseInfo, $session_id)
[],
false
);
/*api_mail_html(
api_get_person_name(
$user_info['firstname'].' '.$user_info['lastname'],
null,
PERSON_NAME_EMAIL_ADDRESS
),
$user_info['email'],
$subject,
$message,
$senderName,
$senderEmail
);*/
}
}
}
@ -4040,9 +3813,11 @@ function sendAlertToUsers($workId, $courseInfo, $session_id)
*/
function checkExistingWorkFileName($filename, $workId)
{
$work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
$table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
$filename = Database::escape_string($filename);
$sql = "SELECT title FROM $work_table
$workId = (int) $workId;
$sql = "SELECT title FROM $table
WHERE parent_id = $workId AND title = '$filename' AND active = 1";
$result = Database::query($sql);
@ -4087,12 +3862,13 @@ function processWorkForm(
$fileInfo = pathinfo($values['title']);
if (isset($fileInfo['extension']) && !empty($fileInfo['extension'])) {
$extension = '.'.$fileInfo['extension'];
$values['title'] = $fileInfo['filename'];
}
}
$title = $values['title'].$extension;
$description = $values['description'];
$contains_file = isset($values['contains_file']) && !empty($values['contains_file']) ? intval($values['contains_file']) : 0;
$description = isset($values['description']) ? $values['description'] : '';
$containsFile = isset($values['contains_file']) && !empty($values['contains_file']) ? (int) $values['contains_file'] : 0;
$saveWork = true;
$filename = null;
@ -4101,7 +3877,8 @@ function processWorkForm(
$workData = [];
$message = null;
if ($values['contains_file']) {
if ($containsFile) {
$saveWork = false;
if ($checkDuplicated) {
if (checkExistingWorkFileName($file['name'], $workInfo['id'])) {
$saveWork = false;
@ -4115,11 +3892,13 @@ function processWorkForm(
}
if (isset($result['error'])) {
$saveWork = false;
if ($showFlashMessage) {
$message = $result['error'];
}
$saveWork = false;
if (empty($result['error']) && isset($result['url']) && !empty($result['url'])) {
$saveWork = true;
}
}
}
@ -4151,7 +3930,7 @@ function processWorkForm(
'filetype' => 'file',
'title' => $title,
'description' => $description,
'contains_file' => $contains_file,
'contains_file' => $containsFile,
'active' => $active,
'accepted' => '1',
'qualificator_id' => 0,
@ -4251,7 +4030,7 @@ function processWorkForm(
}
}
$workData = get_work_data_by_id($workId);
if ($showFlashMessage) {
if ($workData && $showFlashMessage) {
Display::addFlash(Display::return_message(get_lang('DocAdd')));
}
}
@ -4972,7 +4751,6 @@ function updateSettings($courseInfo, $showScore, $studentDeleteOwnPublication)
Session::write('_course', $courseInfo);
// changing the tool setting: is a student allowed to delete his/her own document
// counting the number of occurrences of this setting (if 0 => add, if 1 => update)
$query = "SELECT * FROM $table_course_setting
WHERE
@ -5035,10 +4813,10 @@ function makeInvisible($item_id, $course_info)
return false;
}
$work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
$table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
$item_id = intval($item_id);
$course_id = $course_info['real_id'];
$sql = "UPDATE ".$work_table."
$sql = "UPDATE $table
SET accepted = 0
WHERE c_id = $course_id AND id = '".$item_id."'";
Database::query($sql);
@ -5117,7 +4895,6 @@ function showStudentList($workId)
],
];
$token = null;
$url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_work_student_list_overview&work_id='.$workId.'&'.api_get_cidreq();
$columns = [
@ -5356,7 +5133,6 @@ function getFileContents($id, $course_info, $sessionId = 0, $correction = false)
}
$table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
if (!empty($course_info['real_id'])) {
$sql = 'SELECT *
FROM '.$table.'
@ -5533,7 +5309,6 @@ function exportAllStudentWorkFromPublication(
}
$workData = get_work_data_by_id($workId);
if (empty($workData)) {
return false;
}
@ -5667,9 +5442,7 @@ function downloadAllFilesPerUser($userId, $courseInfo)
$tempZipFile = api_get_path(SYS_ARCHIVE_PATH).api_get_unique_id().".zip";
$coursePath = api_get_path(SYS_COURSE_PATH).$courseInfo['path'].'/work/';
$zip = new PclZip($tempZipFile);
$workPerUser = getWorkPerUser($userId);
if (!empty($workPerUser)) {

@ -227,7 +227,7 @@ switch ($action) {
}
break;
case 'move':
/* Move file form request */
// Move file form request
if ($is_allowed_to_edit) {
if (!empty($item_id)) {
$content = generateMoveForm(
@ -340,7 +340,7 @@ switch ($action) {
break;
case 'list':
/* Display list of student publications */
/* Display list of student publications */
if (!empty($my_folder_data['description'])) {
$content = '<div>'.
get_lang('Description').':'.Security::remove_XSS($my_folder_data['description'], STUDENT).

@ -129,13 +129,53 @@ if (!api_is_invitee()) {
get_lang('Actions'),
];
$column_model = [
['name' => 'type', 'index' => 'file', 'width' => '5', 'align' => 'left', 'search' => 'false', 'sortable' => 'false'],
['name' => 'title', 'index' => 'title', 'width' => '40', 'align' => 'left', 'search' => 'false', 'wrap_cell' => 'true'],
['name' => 'qualification', 'index' => 'qualification', 'width' => '30', 'align' => 'center', 'search' => 'true'],
['name' => 'sent_date', 'index' => 'sent_date', 'width' => '30', 'align' => 'left', 'search' => 'true', 'wrap_cell' => 'true'],
['name' => 'qualificator_id', 'index' => 'qualificator_id', 'width' => '20', 'align' => 'left', 'search' => 'true'],
['name' => 'actions', 'index' => 'actions', 'width' => '20', 'align' => 'left', 'search' => 'false', 'sortable' => 'false'],
$columnModel = [
[
'name' => 'type',
'index' => 'file',
'width' => '5',
'align' => 'left',
'search' => 'false',
'sortable' => 'false',
],
[
'name' => 'title',
'index' => 'title',
'width' => '40',
'align' => 'left',
'search' => 'false',
'wrap_cell' => 'true',
],
[
'name' => 'qualification',
'index' => 'qualification',
'width' => '30',
'align' => 'center',
'search' => 'true',
],
[
'name' => 'sent_date',
'index' => 'sent_date',
'width' => '30',
'align' => 'left',
'search' => 'true',
'wrap_cell' => 'true',
],
[
'name' => 'qualificator_id',
'index' => 'qualificator_id',
'width' => '20',
'align' => 'left',
'search' => 'true',
],
[
'name' => 'actions',
'index' => 'actions',
'width' => '20',
'align' => 'left',
'search' => 'false',
'sortable' => 'false',
],
];
} else {
$type = 'complex';
@ -148,32 +188,67 @@ if (!api_is_invitee()) {
get_lang('Actions'),
];
$column_model = [
['name' => 'type', 'index' => 'file', 'width' => '5', 'align' => 'left', 'search' => 'false', 'sortable' => 'false'],
['name' => 'title', 'index' => 'title', 'width' => '60', 'align' => 'left', 'search' => 'false', 'wrap_cell' => "true"],
['name' => 'qualification', 'index' => 'qualification', 'width' => '30', 'align' => 'center', 'search' => 'true'],
['name' => 'sent_date', 'index' => 'sent_date', 'width' => '30', 'align' => 'left', 'search' => 'true', 'wrap_cell' => 'true', 'sortable' => 'false'],
['name' => 'actions', 'index' => 'actions', 'width' => '20', 'align' => 'left', 'search' => 'false', 'sortable' => 'false'],
$columnModel = [
[
'name' => 'type',
'index' => 'file',
'width' => '5',
'align' => 'left',
'search' => 'false',
'sortable' => 'false',
],
[
'name' => 'title',
'index' => 'title',
'width' => '60',
'align' => 'left',
'search' => 'false',
'wrap_cell' => "true",
],
[
'name' => 'qualification',
'index' => 'qualification',
'width' => '30',
'align' => 'center',
'search' => 'true',
],
[
'name' => 'sent_date',
'index' => 'sent_date',
'width' => '30',
'align' => 'left',
'search' => 'true',
'wrap_cell' => 'true',
'sortable' => 'false',
],
[
'name' => 'actions',
'index' => 'actions',
'width' => '20',
'align' => 'left',
'search' => 'false',
'sortable' => 'false',
],
];
}
$extra_params = [
$extraParams = [
'autowidth' => 'true',
'height' => 'auto',
'sortname' => 'firstname',
'sortname' => 'sent_date',
'sortorder' => 'desc',
];
$url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_work_user_list&work_id='.$workId.'&type='.$type.'&'.api_get_cidreq();
$content .= '
<script>
$(function() {
'.Display::grid_js('results', $url, $columns, $column_model, $extra_params).'
'.Display::grid_js('results', $url, $columns, $columnModel, $extraParams).'
});
</script>
';
$content .= getAllDocumentsFromWorkToString($workId, $courseInfo);
$tableWork = Display::grid_html('results');
$content .= Display::panel($tableWork);
}

@ -124,7 +124,7 @@ switch ($action) {
exit;
break;
case 'make_visible':
/* Visible */
/* Visible */
if ($is_allowed_to_edit) {
if (!empty($itemId)) {
if (isset($itemId) && $itemId == 'all') {
@ -138,7 +138,7 @@ switch ($action) {
}
break;
case 'make_invisible':
/* Invisible */
/* Invisible */
if (!empty($itemId)) {
if (isset($itemId) && $itemId == 'all') {
} else {
@ -370,7 +370,6 @@ echo $documentsAddedInWork;
$tableWork = Display::grid_html('results');
echo workGetExtraFieldData($workId);
echo Display::panel($tableWork);
echo '<div class="list-work-results">';

@ -37,7 +37,7 @@ protectWork($courseInfo, $workId);
$htmlHeadXtra[] = api_get_jqgrid_js();
if (!empty($group_id)) {
$group_properties = GroupManager :: get_group_properties($group_id);
$group_properties = GroupManager::get_group_properties($group_id);
$show_work = false;
if (api_is_allowed_to_edit(false, true)) {
@ -82,7 +82,8 @@ echo '<a href="'.api_get_path(WEB_CODE_PATH).'work/work.php?'.api_get_cidreq().'
echo '</div>';
if (!empty($my_folder_data['description'])) {
echo '<p><div><strong>'.get_lang('Description').':</strong><p>'.Security::remove_XSS($my_folder_data['description']).'</p></div></p>';
echo '<p><div><strong>'.get_lang('Description').':</strong><p>'.
Security::remove_XSS($my_folder_data['description']).'</p></div></p>';
}
$check_qualification = intval($my_folder_data['qualification']);

@ -106,11 +106,13 @@ $output = '';
if (!empty($workId)) {
if (empty($_GET['list']) or Security::remove_XSS($_GET['list']) == 'with') {
$output .= '<a href="'.api_get_self().'?'.api_get_cidreq().'&id='.$workId.'&list=without">'.
Display::return_icon('exercice_uncheck.png', get_lang('ViewUsersWithoutTask'), '', ICON_SIZE_MEDIUM)."</a>";
Display::return_icon('exercice_uncheck.png', get_lang('ViewUsersWithoutTask'), '', ICON_SIZE_MEDIUM).
"</a>";
} else {
if (!isset($_GET['action']) || (isset($_GET['action']) && $_GET['action'] != 'send_mail')) {
$output .= '<a href="'.api_get_self().'?'.api_get_cidreq().'&id='.$workId.'&list=without&action=send_mail&sec_token='.$token.'">'.
Display::return_icon('mail_send.png', get_lang('ReminderMessage'), '', ICON_SIZE_MEDIUM)."</a>";
Display::return_icon('mail_send.png', get_lang('ReminderMessage'), '', ICON_SIZE_MEDIUM).
"</a>";
} else {
$output .= Display::return_icon('mail_send_na.png', get_lang('ReminderMessage'), '', ICON_SIZE_MEDIUM);
}

Loading…
Cancel
Save