lp_list.php 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. use Chamilo\CourseBundle\Entity\CLpCategory;
  4. use ChamiloSession as Session;
  5. /**
  6. * This file was originally the copy of document.php, but many modifications happened since then ;
  7. * the direct file view is not any more needed, if the user uploads a SCORM zip file, a directory
  8. * will be automatically created for it, and the files will be uncompressed there for example ;.
  9. *
  10. * @package chamilo.learnpath
  11. *
  12. * @author Yannick Warnier <ywarnier@beeznest.org>
  13. */
  14. $this_section = SECTION_COURSES;
  15. //@todo who turns on $lp_controller_touched?
  16. if (empty($lp_controller_touched) || $lp_controller_touched != 1) {
  17. header('Location: lp_controller.php?action=list&'.api_get_cidreq());
  18. exit;
  19. }
  20. require_once __DIR__.'/../inc/global.inc.php';
  21. api_protect_course_script();
  22. $courseDir = api_get_course_path().'/scorm';
  23. $baseWordDir = $courseDir;
  24. /**
  25. * Display initialisation and security checks.
  26. */
  27. // Extra javascript functions for in html head:
  28. $htmlHeadXtra[] = "<script>
  29. function confirmation(name) {
  30. if (confirm(\" ".trim(get_lang('Are you sure to delete'))." \"+name+\"?\")) {
  31. return true;
  32. } else {
  33. return false;
  34. }
  35. }
  36. </script>";
  37. $nameTools = get_lang('Learning paths');
  38. Event::event_access_tool(TOOL_LEARNPATH);
  39. /* Require the search widget and prepare the header with its stuff. */
  40. if (api_get_setting('search_enabled') === 'true') {
  41. require api_get_path(LIBRARY_PATH).'search/search_widget.php';
  42. search_widget_prepare($htmlHeadXtra);
  43. }
  44. $courseId = api_get_course_int_id();
  45. $sessionId = api_get_session_id();
  46. $is_allowed_to_edit = api_is_allowed_to_edit(null, true);
  47. $courseInfo = api_get_course_info();
  48. $subscriptionSettings = learnpath::getSubscriptionSettings();
  49. /* Introduction section (editable by course admins) */
  50. $introduction = Display::return_introduction_section(
  51. TOOL_LEARNPATH,
  52. [
  53. 'CreateDocumentWebDir' => api_get_path(WEB_COURSE_PATH)
  54. .api_get_course_path().'/document/',
  55. 'CreateDocumentDir' => '../..'.api_get_path(REL_COURSE_PATH)
  56. .api_get_course_path().'/document/',
  57. 'BaseHref' => api_get_path(WEB_COURSE_PATH)
  58. .api_get_course_path().'/',
  59. ]
  60. );
  61. $message = '';
  62. $actions = '';
  63. if ($is_allowed_to_edit) {
  64. $actionLeft = '';
  65. $actionLeft .= Display::url(
  66. Display::return_icon(
  67. 'new_learnpath.png',
  68. get_lang('Create new learning path'),
  69. '',
  70. ICON_SIZE_MEDIUM
  71. ),
  72. api_get_self().'?'.api_get_cidreq().'&action=add_lp'
  73. );
  74. $actionLeft .= Display::url(
  75. Display::return_icon(
  76. 'import_scorm.png',
  77. get_lang('Import AICC, SCORM and Chamilo learning path'),
  78. '',
  79. ICON_SIZE_MEDIUM
  80. ),
  81. '../upload/index.php?'.api_get_cidreq().'&curdirpath=/&tool='.TOOL_LEARNPATH
  82. );
  83. if (api_get_setting('service_ppt2lp', 'active') === 'true') {
  84. $actionLeft .= Display::url(
  85. Display::return_icon(
  86. 'import_powerpoint.png',
  87. get_lang('Chamilo RAPID'),
  88. '',
  89. ICON_SIZE_MEDIUM
  90. ),
  91. '../upload/upload_ppt.php?'.api_get_cidreq().'&curdirpath=/&tool='.TOOL_LEARNPATH
  92. );
  93. }
  94. if (!$sessionId) {
  95. $actionLeft .= Display::url(
  96. Display::return_icon(
  97. 'new_folder.png',
  98. get_lang('Add category'),
  99. [],
  100. ICON_SIZE_MEDIUM
  101. ),
  102. api_get_self().'?'.api_get_cidreq().'&action=add_lp_category'
  103. );
  104. }
  105. $actions = Display::toolbarAction('actions-lp', [$actionLeft]);
  106. }
  107. $token = Security::get_token();
  108. $categoriesTempList = learnpath::getCategories($courseId);
  109. $categoryTest = new CLpCategory();
  110. $categoryTest->setId(0);
  111. $categoryTest->setName(get_lang('Without category'));
  112. $categoryTest->setPosition(0);
  113. $categories = [
  114. $categoryTest,
  115. ];
  116. if (!empty($categoriesTempList)) {
  117. $categories = array_merge($categories, $categoriesTempList);
  118. }
  119. $userId = api_get_user_id();
  120. $userInfo = api_get_user_info();
  121. $lpIsShown = false;
  122. $filteredCategoryId = ($action === 'view_category' && !empty($_GET['id'])) ? intval($_GET['id']) : 0;
  123. if ($filteredCategoryId) {
  124. /** @var CLpCategory $category */
  125. foreach ($categories as $category) {
  126. if ($category->getId() != $filteredCategoryId) {
  127. continue;
  128. }
  129. $interbreadcrumb[] = ['name' => $nameTools, 'url' => api_get_self()];
  130. $nameTools = strip_tags($category->getName());
  131. }
  132. }
  133. $test_mode = api_get_setting('server_type');
  134. $showBlockedPrerequisite = api_get_configuration_value('show_prerequisite_as_blocked');
  135. $allowLpChamiloExport = api_get_configuration_value('allow_lp_chamilo_export');
  136. $allowMinTime = Tracking::minimumTimeAvailable($sessionId, $courseId);
  137. $accumulateWorkTimeTotal = 0;
  138. if ($allowMinTime) {
  139. $accumulateWorkTimeTotal = learnpath::getAccumulateWorkTimeTotal($courseId);
  140. }
  141. $user = api_get_user_entity($userId);
  142. $ending = true;
  143. $isInvitee = api_is_invitee();
  144. $hideScormExportLink = api_get_setting('hide_scorm_export_link');
  145. $hideScormCopyLink = api_get_setting('hide_scorm_copy_link');
  146. $hideScormPdfLink = api_get_setting('hide_scorm_pdf_link');
  147. $options = learnpath::getIconSelect();
  148. $cidReq = api_get_cidreq();
  149. $defaultLpIcon = Display::return_icon(
  150. 'learnpath.png',
  151. get_lang('Learning path name')
  152. );
  153. $defaultDisableLpIcon = Display::return_icon(
  154. 'learnpath_na.png',
  155. get_lang('Learning path name')
  156. );
  157. $courseSettingsIcon = Display::return_icon(
  158. 'settings.png',
  159. get_lang('Course settings')
  160. );
  161. $courseSettingsDisableIcon = Display::return_icon(
  162. 'settings_na.png',
  163. get_lang('Course settings')
  164. );
  165. $enableAutoLaunch = api_get_course_setting('enable_lp_auto_launch');
  166. $gameMode = api_get_setting('gamification_mode');
  167. $data = [];
  168. /** @var CLpCategory $item */
  169. foreach ($categories as $item) {
  170. $categoryId = $item->getId();
  171. if ($categoryId !== 0 && $subscriptionSettings['allow_add_users_to_lp_category'] == true) {
  172. // "Without category" has id = 0
  173. $categoryVisibility = api_get_item_visibility(
  174. $courseInfo,
  175. TOOL_LEARNPATH_CATEGORY,
  176. $categoryId,
  177. $sessionId
  178. );
  179. if (!$is_allowed_to_edit) {
  180. if ($categoryVisibility !== 1 && $categoryVisibility != -1) {
  181. continue;
  182. }
  183. }
  184. if ($user && !learnpath::categoryIsVisibleForStudent($item, $user)) {
  185. continue;
  186. }
  187. }
  188. $list = new LearnpathList(
  189. $userId,
  190. $courseInfo,
  191. $sessionId,
  192. null,
  193. false,
  194. $categoryId
  195. );
  196. $flat_list = $list->get_flat_list();
  197. // Hiding categories with out LPs (only for student)
  198. if (empty($flat_list) && !$is_allowed_to_edit) {
  199. continue;
  200. }
  201. $listData = [];
  202. $lpTimeList = [];
  203. if ($allowMinTime) {
  204. $lpTimeList = Tracking::getCalculateTime($userId, $courseId, $sessionId);
  205. }
  206. if (!empty($flat_list)) {
  207. $max = count($flat_list);
  208. $counter = 0;
  209. $current = 0;
  210. $autolaunch_exists = false;
  211. $progressList = learnpath::getProgressFromLpList(
  212. array_column($flat_list, 'lp_old_id'),
  213. $userId,
  214. $courseId,
  215. $sessionId
  216. );
  217. $now = time();
  218. foreach ($flat_list as $id => $details) {
  219. $id = $details['lp_old_id'];
  220. if (!$is_allowed_to_edit && $details['lp_visibility'] == 0) {
  221. // This is a student and this path is invisible, skip.
  222. continue;
  223. }
  224. $lpVisibility = learnpath::is_lp_visible_for_student($id, $userId, $courseInfo);
  225. // Check if the learnpath is visible for student.
  226. if (!$is_allowed_to_edit) {
  227. $isBlocked = learnpath::isBlockedByPrerequisite(
  228. $userId,
  229. $details['prerequisite'],
  230. $courseInfo,
  231. $sessionId
  232. );
  233. if ($lpVisibility === false && $isBlocked && $showBlockedPrerequisite === false) {
  234. continue;
  235. }
  236. }
  237. $start_time = $end_time = '';
  238. if ($is_allowed_to_edit) {
  239. if (!empty($details['publicated_on'])) {
  240. $start_time = api_convert_and_format_date($details['publicated_on'], DATE_TIME_FORMAT_LONG_24H);
  241. }
  242. if (!empty($details['expired_on'])) {
  243. $end_time = api_convert_and_format_date($details['expired_on'], DATE_TIME_FORMAT_LONG_24H);
  244. }
  245. } else {
  246. $time_limits = false;
  247. // This is an old LP (from a migration 1.8.7) so we do nothing
  248. if (empty($details['created_on']) && empty($details['modified_on'])) {
  249. $time_limits = false;
  250. }
  251. // Checking if expired_on is ON
  252. if ($details['expired_on'] != '') {
  253. $time_limits = true;
  254. }
  255. if ($time_limits) {
  256. // Check if start time
  257. if (!empty($details['publicated_on']) && !empty($details['expired_on'])) {
  258. $start_time = api_strtotime($details['publicated_on'], 'UTC');
  259. $end_time = api_strtotime($details['expired_on'], 'UTC');
  260. $is_actived_time = false;
  261. if ($now > $start_time && $end_time > $now) {
  262. $is_actived_time = true;
  263. }
  264. if (!$is_actived_time) {
  265. continue;
  266. }
  267. }
  268. }
  269. }
  270. $counter++;
  271. $oddclass = 'row_even';
  272. if (($counter % 2) == 0) {
  273. $oddclass = 'row_odd';
  274. }
  275. $url_start_lp = 'lp_controller.php?'.$cidReq.'&action=view&lp_id='.$id;
  276. $name = strip_tags(Security::remove_XSS($details['lp_name']));
  277. $extra = null;
  278. if ($is_allowed_to_edit) {
  279. // @todo This line is what makes the teacher switch to
  280. // student view automatically. Many teachers are confused
  281. // by that, so maybe a solution can be found to avoid it
  282. $url_start_lp .= '&isStudentView=true';
  283. $dsp_desc = '<em>'.$details['lp_maker'].'</em> '
  284. .($lpVisibility
  285. ? ''
  286. : ' - ('.get_lang('Learners cannot see this learning path').')');
  287. $extra = '<div class ="lp_content_type_label">'.$dsp_desc.'</div>';
  288. }
  289. $my_title = $name;
  290. $icon_learnpath = $defaultLpIcon;
  291. if ($details['lp_visibility'] == 0) {
  292. $my_title = Display::tag(
  293. 'font',
  294. $name,
  295. ['class' => 'text-muted']
  296. );
  297. $icon_learnpath = $defaultDisableLpIcon;
  298. }
  299. if (!empty($options)) {
  300. $icon = learnpath::getSelectedIconHtml($id);
  301. if (!empty($icon)) {
  302. $icon_learnpath = $icon;
  303. }
  304. }
  305. // Students can see the lp but is inactive
  306. if (!$is_allowed_to_edit && $lpVisibility == false &&
  307. $showBlockedPrerequisite == true
  308. ) {
  309. $my_title = Display::tag(
  310. 'font',
  311. $name,
  312. ['class' => 'text-muted']
  313. );
  314. $icon_learnpath = $defaultDisableLpIcon;
  315. $url_start_lp = '#';
  316. }
  317. $dsp_desc = '';
  318. $dsp_export = '';
  319. $dsp_build = '';
  320. $dsp_delete = '';
  321. $dsp_visible = '';
  322. $trackingAction = '';
  323. $dsp_default_view = '';
  324. $dsp_debug = '';
  325. $dsp_order = '';
  326. $progress = 0;
  327. if (!$isInvitee) {
  328. $progress = isset($progressList[$id]) && !empty($progressList[$id]) ? $progressList[$id] : 0;
  329. }
  330. if ($is_allowed_to_edit) {
  331. $dsp_progress = '<center>'.$progress.'%</center>';
  332. } else {
  333. $dsp_progress = '';
  334. if (!$isInvitee) {
  335. $dsp_progress = learnpath::get_progress_bar($progress, '%');
  336. }
  337. }
  338. if ($progress < 100) {
  339. $ending = false;
  340. }
  341. $dsp_time = '';
  342. $linkMinTime = '';
  343. if ($allowMinTime) {
  344. // Minimum time (in minutes) to pass the learning path
  345. $accumulateWorkTime = learnpath::getAccumulateWorkTimePrerequisite($id, $courseId);
  346. if ($accumulateWorkTime > 0) {
  347. $lpTime = isset($lpTimeList[TOOL_LEARNPATH][$id]) ? $lpTimeList[TOOL_LEARNPATH][$id] : 0;
  348. // Connect with the plugin_licences_course_session table
  349. // which indicates what percentage of the time applies
  350. $perc = 100;
  351. // Percentage of the learning paths
  352. $pl = 0;
  353. if (!empty($accumulateWorkTimeTotal)) {
  354. $pl = $accumulateWorkTime / $accumulateWorkTimeTotal;
  355. }
  356. // Minimum time for each learning path
  357. $accumulateWorkTime = ($pl * $accumulateWorkTimeTotal * $perc / 100);
  358. // If the time spent is less than necessary, then we show an icon in the actions column indicating the warning
  359. if ($lpTime < ($accumulateWorkTime * 60)) {
  360. $linkMinTime = Display::return_icon(
  361. 'warning.png',
  362. get_lang('You didn\'t spend the minimum time required in the learning path.').' - '.api_time_to_hms($lpTime).' / '.api_time_to_hms(
  363. $accumulateWorkTime * 60
  364. )
  365. );
  366. } else {
  367. $linkMinTime = Display::return_icon(
  368. 'check.png',
  369. get_lang('You didn\'t spend the minimum time required in the learning path.').' - '.api_time_to_hms($lpTime).' / '.api_time_to_hms(
  370. $accumulateWorkTime * 60
  371. )
  372. );
  373. }
  374. $linkMinTime .= '&nbsp;<b>'.api_time_to_hms($lpTime).' / '.api_time_to_hms($accumulateWorkTime * 60).'</b>';
  375. // Calculate the percentage exceeded of the time for the "exceeding the minimum time" bar
  376. if ($lpTime >= ($accumulateWorkTime * 60)) {
  377. $time_progress_perc = '100%';
  378. $time_progress_value = 100;
  379. } else {
  380. $time_progress_value = (int) (($lpTime * 100) / ($accumulateWorkTime * 60));
  381. }
  382. if ($time_progress_value < 100) {
  383. $ending = false;
  384. }
  385. $dsp_time = learnpath::get_progress_bar($time_progress_value, '%');
  386. }
  387. }
  388. $token_parameter = "&sec_token=$token";
  389. $dsp_edit_lp = null;
  390. $dsp_publish = null;
  391. $dsp_reinit = null;
  392. $subscribeUsers = null;
  393. $dsp_disk = null;
  394. $copy = null;
  395. $lp_auto_launch_icon = null;
  396. $actionSeriousGame = null;
  397. $actionUpdateScormFile = '';
  398. $actionExportToCourseBuild = '';
  399. // Only for "Chamilo" packages
  400. $allowExportCourseFormat = $allowLpChamiloExport && $details['lp_maker'] === 'Chamilo';
  401. if ($is_allowed_to_edit) {
  402. // EDIT LP
  403. if ($sessionId == $details['lp_session']) {
  404. $dsp_edit_lp = Display::url(
  405. $courseSettingsIcon,
  406. 'lp_controller.php?'.$cidReq."&action=edit&lp_id=$id"
  407. );
  408. } else {
  409. $dsp_edit_lp = $courseSettingsDisableIcon;
  410. }
  411. // BUILD
  412. if ($sessionId == $details['lp_session']) {
  413. if ($details['lp_type'] == 1 || $details['lp_type'] == 2) {
  414. $dsp_build = Display::url(
  415. Display::return_icon(
  416. 'edit.png',
  417. get_lang('Edit learnpath')
  418. ),
  419. 'lp_controller.php?'.$cidReq.'&'
  420. .http_build_query(
  421. [
  422. 'action' => 'add_item',
  423. 'type' => 'step',
  424. 'lp_id' => $id,
  425. 'isStudentView' => 'false',
  426. ]
  427. )
  428. );
  429. } else {
  430. $dsp_build = Display::return_icon(
  431. 'edit_na.png',
  432. get_lang('Edit learnpath')
  433. );
  434. }
  435. } else {
  436. $dsp_build = Display::return_icon(
  437. 'edit_na.png',
  438. get_lang('Edit learnpath')
  439. );
  440. }
  441. /* VISIBILITY COMMAND */
  442. /* Session test not necessary if we want to show base course learning
  443. paths inside the session.
  444. See http://support.chamilo.org/projects/chamilo-18/wiki/Tools_and_sessions).
  445. */
  446. if (!isset($details['subscribe_users']) ||
  447. $details['subscribe_users'] != 1
  448. ) {
  449. if ($details['lp_visibility'] == 0) {
  450. $dsp_visible = Display::url(
  451. Display::return_icon(
  452. 'invisible.png',
  453. get_lang('Show')
  454. ),
  455. api_get_self().'?'.$cidReq."&lp_id=$id&action=toggle_visible&new_status=1"
  456. );
  457. } else {
  458. $dsp_visible = Display::url(
  459. Display::return_icon('visible.png', get_lang('Hide')),
  460. api_get_self().'?'.$cidReq."&lp_id=$id&action=toggle_visible&new_status=0"
  461. );
  462. }
  463. }
  464. // Tracking command
  465. $trackingActionUrl = 'lp_controller.php?'.$cidReq.'&'.http_build_query(
  466. ['action' => 'report', 'lp_id' => $id]
  467. );
  468. $trackingAction = Display::url(
  469. Display::return_icon(
  470. 'test_results.png',
  471. get_lang('Results and feedback')
  472. ),
  473. $trackingActionUrl
  474. );
  475. /* PUBLISH COMMAND */
  476. if ($sessionId == $details['lp_session']) {
  477. if ($details['lp_published'] == 'i') {
  478. $dsp_publish = Display::url(
  479. Display::return_icon(
  480. 'lp_publish_na.png',
  481. get_lang('Publish on course homepage')
  482. ),
  483. api_get_self().'?'.$cidReq."&lp_id=$id&action=toggle_publish&new_status=v"
  484. );
  485. } else {
  486. $dsp_publish = Display::url(
  487. Display::return_icon(
  488. 'lp_publish.png',
  489. get_lang('do not publish')
  490. ),
  491. api_get_self().'?'.$cidReq."&lp_id=$id&action=toggle_publish&new_status=i"
  492. );
  493. }
  494. } else {
  495. $dsp_publish = Display::return_icon(
  496. 'lp_publish_na.png',
  497. get_lang('do not publish')
  498. );
  499. }
  500. /* MULTIPLE ATTEMPTS OR SERIOUS GAME MODE
  501. SERIOUSGAME MODE is a special mode where :
  502. * If a user exits the learning path before finishing it, he comes back where he left next time he tries
  503. * When lp status is completed, user can still modify the attempt (adds/time change score, and browse it)
  504. * It is thus a mix betwenn multiple attempt and mono attempt
  505. */
  506. if ($sessionId == $details['lp_session']) {
  507. if ($details['seriousgame_mode'] == 1 && $details['lp_prevent_reinit'] == 1) {
  508. // seriousgame mode | next = single
  509. $dsp_reinit = Display::url(
  510. Display::return_icon(
  511. 'reload.png',
  512. get_lang('Prevent multiple attempts')
  513. ),
  514. 'lp_controller.php?'.$cidReq."&action=switch_attempt_mode&lp_id=$id"
  515. );
  516. }
  517. if ($details['seriousgame_mode'] == 0 &&
  518. $details['lp_prevent_reinit'] == 1
  519. ) {
  520. // single mode | next = multiple
  521. $dsp_reinit = Display::url(
  522. Display::return_icon(
  523. 'reload_na.png',
  524. get_lang('Allow multiple attempts')
  525. ),
  526. 'lp_controller.php?'.$cidReq."&action=switch_attempt_mode&lp_id=$id"
  527. );
  528. }
  529. if ($details['seriousgame_mode'] == 0 &&
  530. $details['lp_prevent_reinit'] == 0
  531. ) {
  532. // multiple mode | next = seriousgame
  533. $dsp_reinit = Display::url(
  534. Display::return_icon(
  535. 'reload.png',
  536. get_lang('Allow multiple attempts')
  537. ),
  538. 'lp_controller.php?'.$cidReq."&action=switch_attempt_mode&lp_id=$id"
  539. );
  540. }
  541. } else {
  542. $dsp_reinit = Display::return_icon(
  543. 'reload_na.png',
  544. get_lang('Allow multiple attempts')
  545. );
  546. }
  547. /* SCREEN LP VIEW */
  548. if ($sessionId == $details['lp_session']) {
  549. switch ($details['lp_view_mode']) {
  550. case 'fullscreen':
  551. $dsp_default_view = Display::url(
  552. Display::return_icon(
  553. 'view_fullscreen.png',
  554. get_lang('Current view mode: fullscreen')
  555. ),
  556. 'lp_controller.php?'.$cidReq.'&action=switch_view_mode&lp_id='.$id.$token_parameter
  557. );
  558. break;
  559. case 'embedded':
  560. $dsp_default_view = Display::url(
  561. Display::return_icon(
  562. 'view_left_right.png',
  563. get_lang('Current view mode: embedded')
  564. ),
  565. 'lp_controller.php?'.$cidReq.'&action=switch_view_mode&lp_id='.$id.$token_parameter
  566. );
  567. break;
  568. case 'embedframe':
  569. $dsp_default_view = Display::url(
  570. Display::return_icon(
  571. 'view_nofullscreen.png',
  572. get_lang('Current view mode: external embed. Use only for embedding in external sites.')
  573. ),
  574. 'lp_controller.php?'.$cidReq.'&action=switch_view_mode&lp_id='.$id.$token_parameter
  575. );
  576. break;
  577. case 'impress':
  578. $dsp_default_view = Display::url(
  579. Display::return_icon(
  580. 'window_list_slide.png',
  581. get_lang('Current view mode: Impress')
  582. ),
  583. 'lp_controller.php?'.$cidReq.'&action=switch_view_mode&lp_id='.$id.$token_parameter
  584. );
  585. break;
  586. }
  587. } else {
  588. if ($details['lp_view_mode'] === 'fullscreen') {
  589. $dsp_default_view = Display::return_icon(
  590. 'view_fullscreen_na.png',
  591. get_lang('Current view mode: embedded')
  592. );
  593. } else {
  594. $dsp_default_view = Display::return_icon(
  595. 'view_left_right_na.png',
  596. get_lang('Current view mode: embedded')
  597. );
  598. }
  599. }
  600. /* DEBUG */
  601. if ($test_mode === 'test' || api_is_platform_admin()) {
  602. if ($details['lp_scorm_debug'] == 1) {
  603. $dsp_debug = Display::url(
  604. Display::return_icon(
  605. 'bug.png',
  606. get_lang('Hide debug')
  607. ),
  608. "lp_controller.php?$cidReq&action=switch_scorm_debug&lp_id=$id"
  609. );
  610. } else {
  611. $dsp_debug = Display::url(
  612. Display::return_icon(
  613. 'bug_na.png',
  614. get_lang('Show debug')
  615. ),
  616. 'lp_controller.php?'.$cidReq."&action=switch_scorm_debug&lp_id=$id"
  617. );
  618. }
  619. }
  620. /* Export */
  621. if ($details['lp_type'] == 1) {
  622. $dsp_disk = Display::url(
  623. Display::return_icon('cd.png', get_lang('Export as SCORM')),
  624. api_get_self()."?$cidReq&action=export&lp_id=$id"
  625. );
  626. } elseif ($details['lp_type'] == 2) {
  627. $dsp_disk = Display::url(
  628. Display::return_icon('cd.png', get_lang('Export as SCORM')),
  629. api_get_self()."?$cidReq&action=export&lp_id=$id&export_name="
  630. .api_replace_dangerous_char($name).'.zip'
  631. );
  632. } else {
  633. $dsp_disk = Display::return_icon(
  634. 'cd_na.png',
  635. get_lang('Export as SCORM')
  636. );
  637. }
  638. // Copy
  639. $copy = Display::url(
  640. Display::return_icon('cd_copy.png', get_lang('Copy')),
  641. api_get_self().'?'.$cidReq."&action=copy&lp_id=$id"
  642. );
  643. // Subscribe users
  644. $subscribeUsers = '';
  645. if ($details['subscribe_users'] == 1 &&
  646. $subscriptionSettings['allow_add_users_to_lp']
  647. ) {
  648. $subscribeUsers = Display::url(
  649. Display::return_icon(
  650. 'user.png',
  651. get_lang('Subscribe users to learning path')
  652. ),
  653. api_get_path(WEB_CODE_PATH)."lp/lp_subscribe_users.php?lp_id=$id&".$cidReq
  654. );
  655. }
  656. /* Auto launch LP code */
  657. if ($enableAutoLaunch == 1) {
  658. if ($details['autolaunch'] == 1 &&
  659. $autolaunch_exists == false
  660. ) {
  661. $autolaunch_exists = true;
  662. $lp_auto_launch_icon = Display::url(
  663. Display::return_icon(
  664. 'launch.png',
  665. get_lang('Disable learning path auto-launch')
  666. ),
  667. api_get_self().'?'.$cidReq."&action=auto_launch&status=0&lp_id=$id"
  668. );
  669. } else {
  670. $lp_auto_launch_icon = Display::url(
  671. Display::return_icon(
  672. 'launch_na.png',
  673. get_lang('Enable learning path auto-launch')
  674. ),
  675. api_get_self().'?'.$cidReq."&action=auto_launch&status=1&lp_id=$id"
  676. );
  677. }
  678. }
  679. // Export to PDF
  680. $export_icon = Display::url(
  681. Display::return_icon(
  682. 'pdf.png',
  683. get_lang('Export to PDF web pages and images')
  684. ),
  685. api_get_self().'?'.$cidReq."&action=export_to_pdf&lp_id=$id"
  686. );
  687. /* Delete */
  688. if ($sessionId == $details['lp_session']) {
  689. $dsp_delete = Display::url(
  690. Display::return_icon(
  691. 'delete.png',
  692. get_lang('Delete')
  693. ),
  694. 'lp_controller.php?'.$cidReq."&action=delete&lp_id=$id",
  695. [
  696. 'onclick' => "javascript: return confirmation('".addslashes($name)."');",
  697. ]
  698. );
  699. } else {
  700. $dsp_delete = Display::return_icon(
  701. 'delete_na.png',
  702. get_lang('Delete')
  703. );
  704. }
  705. /* COLUMN ORDER */
  706. // Only active while session mode is not active
  707. if ($sessionId == 0) {
  708. if ($details['lp_display_order'] == 1 && $max != 1) {
  709. $dsp_order .= Display::url(
  710. Display::return_icon('down.png', get_lang('Move down')),
  711. "lp_controller.php?$cidReq&action=move_lp_down&lp_id=$id&category_id=$categoryId"
  712. );
  713. } elseif ($current == $max - 1 && $max != 1) {
  714. $dsp_order .= Display::url(
  715. Display::return_icon('up.png', get_lang('Move up')),
  716. "lp_controller.php?$cidReq&action=move_lp_up&lp_id=$id&category_id=$categoryId"
  717. );
  718. } elseif ($max == 1) {
  719. $dsp_order = '';
  720. } else {
  721. $dsp_order .= Display::url(
  722. Display::return_icon('down.png', get_lang('Move down')),
  723. "lp_controller.php?$cidReq&action=move_lp_down&lp_id=$id&category_id=$categoryId"
  724. );
  725. $dsp_order .= Display::url(
  726. Display::return_icon('up.png', get_lang('Move up')),
  727. "lp_controller.php?$cidReq&action=move_lp_up&lp_id=$id&category_id=$categoryId"
  728. );
  729. }
  730. }
  731. if ($details['lp_type'] == 2) {
  732. $url = api_get_path(WEB_CODE_PATH).'lp/lp_update_scorm.php?'.$cidReq."&lp_id=$id";
  733. $actionUpdateScormFile = Display::url(
  734. Display::return_icon('upload_file.png', get_lang('Update')),
  735. $url
  736. );
  737. }
  738. if ($allowExportCourseFormat) {
  739. $actionExportToCourseBuild = Display::url(
  740. Display::return_icon(
  741. 'backup.png',
  742. get_lang('Export to Chamilo format')
  743. ),
  744. api_get_self().'?'.$cidReq."&action=export_to_course_build&lp_id=$id"
  745. );
  746. }
  747. if ($gameMode == 1) {
  748. if ($details['seriousgame_mode'] == 0) {
  749. $actionSeriousGame = Display::toolbarButton(
  750. null,
  751. api_get_self().'?'.$cidReq
  752. ."&lp_id=$id&action=toggle_seriousgame",
  753. 'trophy',
  754. 'default',
  755. [
  756. 'class' => 'btn-xs',
  757. 'title' => get_lang('Enable gamification mode'),
  758. ]
  759. );
  760. } else {
  761. $actionSeriousGame = Display::toolbarButton(
  762. null,
  763. api_get_self().'?'.$cidReq
  764. ."&lp_id=$id&action=toggle_seriousgame",
  765. 'trophy',
  766. 'warning',
  767. [
  768. 'class' => 'btn-xs active',
  769. 'title' => get_lang('Disable gamification mode'),
  770. ]
  771. );
  772. }
  773. }
  774. } else {
  775. // Student
  776. $export_icon = Display::url(
  777. Display::return_icon('pdf.png', get_lang('Export to PDF')),
  778. api_get_self().'?'.$cidReq."&action=export_to_pdf&lp_id=$id"
  779. );
  780. }
  781. if ($hideScormExportLink === 'true') {
  782. $dsp_disk = null;
  783. }
  784. if ($hideScormCopyLink === 'true') {
  785. $copy = null;
  786. }
  787. if ($hideScormPdfLink === 'true') {
  788. $export_icon = null;
  789. }
  790. $sessionImage = api_get_session_image(
  791. $details['lp_session'],
  792. $userInfo['status']
  793. );
  794. $listData[] = [
  795. 'learnpath_icon' => $icon_learnpath,
  796. 'url_start' => $url_start_lp,
  797. 'title' => $my_title,
  798. 'session_image' => $sessionImage,
  799. 'extra' => $extra,
  800. 'start_time' => $start_time,
  801. 'end_time' => $end_time,
  802. 'dsp_progress' => $dsp_progress,
  803. 'action_build' => $dsp_build,
  804. 'action_edit' => $dsp_edit_lp,
  805. 'action_tracking' => $trackingAction,
  806. 'action_visible' => $dsp_visible,
  807. 'action_publish' => $dsp_publish,
  808. 'action_reinit' => $dsp_reinit,
  809. 'action_default_view' => $dsp_default_view,
  810. 'action_debug' => $dsp_debug,
  811. 'action_export' => $dsp_disk,
  812. 'action_copy' => $copy,
  813. 'action_auto_launch' => $lp_auto_launch_icon,
  814. 'action_pdf' => $export_icon,
  815. 'action_delete' => $dsp_delete,
  816. 'action_order' => $dsp_order,
  817. 'action_serious_game' => $actionSeriousGame,
  818. 'action_subscribe_users' => $subscribeUsers,
  819. 'action_update_scorm' => $actionUpdateScormFile,
  820. 'action_export_to_course_build' => $actionExportToCourseBuild,
  821. 'info_time_prerequisite' => $linkMinTime,
  822. ];
  823. $lpIsShown = true;
  824. // Counter for number of elements treated
  825. $current++;
  826. } // end foreach ($flat_list)
  827. }
  828. $data[] = [
  829. 'category' => $item,
  830. 'category_visibility' => api_get_item_visibility(
  831. $courseInfo,
  832. TOOL_LEARNPATH_CATEGORY,
  833. $item->getId(),
  834. $sessionId
  835. ),
  836. 'category_is_published' => learnpath::categoryIsPublished(
  837. $item,
  838. $courseInfo['real_id']
  839. ),
  840. 'lp_list' => $listData,
  841. ];
  842. }
  843. // Deleting the objects
  844. Session::erase('oLP');
  845. Session::erase('lpobject');
  846. Session::erase('scorm_view_id');
  847. Session::erase('scorm_item_id');
  848. Session::erase('exerciseResult');
  849. Session::erase('objExercise');
  850. Session::erase('questionList');
  851. learnpath::generate_learning_path_folder($courseInfo);
  852. DocumentManager::removeGeneratedAudioTempFile();
  853. $template = new Template($nameTools);
  854. $template->assign('subscription_settings', $subscriptionSettings);
  855. $template->assign('is_allowed_to_edit', $is_allowed_to_edit);
  856. $template->assign('is_invitee', $isInvitee);
  857. $template->assign('is_ending', $ending);
  858. $template->assign('actions', $actions);
  859. $template->assign('categories', $categories);
  860. $template->assign('message', $message);
  861. $template->assign('introduction', $introduction);
  862. $template->assign('data', $data);
  863. $template->assign('lp_is_shown', $lpIsShown);
  864. $template->assign('filtered_category', $filteredCategoryId);
  865. $template->assign('allow_min_time', $allowMinTime);
  866. $template->displayTemplate('@ChamiloTheme/LearnPath/list.html.twig');