diff --git a/public/main/inc/lib/api.lib.php b/public/main/inc/lib/api.lib.php index fe31007fc9..46b8aeb33b 100644 --- a/public/main/inc/lib/api.lib.php +++ b/public/main/inc/lib/api.lib.php @@ -4082,14 +4082,16 @@ function copy_folder_course_session( $session_id, $course_info, $document, - $source_course_id + $source_course_id, + array $originalFolderNameList = [], + string $originalBaseName = '' ) { $table = Database::get_course_table(TABLE_DOCUMENT); $session_id = intval($session_id); $source_course_id = intval($source_course_id); // Check whether directory already exists. - if (is_dir($pathname) || empty($pathname)) { + if (empty($pathname) || is_dir($pathname)) { return true; } @@ -4100,12 +4102,20 @@ function copy_folder_course_session( return false; } + $baseNoDocument = str_replace('document', '', $originalBaseName); + $folderTitles = explode('/', $baseNoDocument); + $folderTitles = array_filter($folderTitles); + + $table = Database::get_course_table(TABLE_DOCUMENT); + $session_id = (int) $session_id; + $source_course_id = (int) $source_course_id; + $course_id = $course_info['real_id']; $folders = explode(DIRECTORY_SEPARATOR, str_replace($base_path_document.DIRECTORY_SEPARATOR, '', $pathname)); $new_pathname = $base_path_document; $path = ''; - foreach ($folders as $folder) { + foreach ($folders as $index => $folder) { $new_pathname .= DIRECTORY_SEPARATOR.$folder; $path .= DIRECTORY_SEPARATOR.$folder; @@ -4123,13 +4133,22 @@ function copy_folder_course_session( if (0 == $num_rows) { mkdir($new_pathname, api_get_permissions_for_new_directories()); + $title = basename($new_pathname); + + if (isset($folderTitles[$index + 1])) { + $checkPath = $folderTitles[$index +1]; + + if (isset($originalFolderNameList[$checkPath])) { + $title = $originalFolderNameList[$checkPath]; + } + } // Insert new folder with destination session_id. $params = [ 'c_id' => $course_id, 'path' => $path, 'comment' => $document->comment, - 'title' => basename($new_pathname), + 'title' => $title, 'filetype' => 'folder', 'size' => '0', 'session_id' => $session_id, diff --git a/public/main/inc/lib/course.lib.php b/public/main/inc/lib/course.lib.php index f64255fcdb..a1081d8c08 100644 --- a/public/main/inc/lib/course.lib.php +++ b/public/main/inc/lib/course.lib.php @@ -4220,7 +4220,8 @@ class CourseManager $destination_course_code, $destination_session_id, $params = [], - $withBaseContent = true + bool $withBaseContent = true, + bool $copySessionContent = false ) { $course_info = api_get_course_info($source_course_code); @@ -4228,6 +4229,7 @@ class CourseManager $cb = new CourseBuilder('', $course_info); $course = $cb->build($source_session_id, $source_course_code, $withBaseContent); $restorer = new CourseRestorer($course); + $restorer->copySessionContent = $copySessionContent; $restorer->skip_content = $params; $restorer->restore( $destination_course_code, @@ -4260,7 +4262,7 @@ class CourseManager $source_session_id = 0, $destination_session_id = 0, $params = [], - $copySessionContent = false + bool $copySessionContent = false ) { $source_course_info = api_get_course_info($source_course_code); if (!empty($source_course_info)) { @@ -4278,7 +4280,8 @@ class CourseManager $newCourse->getCode(), $destination_session_id, $params, - true + true, + $copySessionContent ); if ($result) { return $newCourse; diff --git a/public/main/inc/lib/promotion.lib.php b/public/main/inc/lib/promotion.lib.php index a67956fd8e..1b81c3efbb 100644 --- a/public/main/inc/lib/promotion.lib.php +++ b/public/main/inc/lib/promotion.lib.php @@ -104,7 +104,7 @@ class Promotion extends Model foreach ($session_list as $item) { $sid = SessionManager::copy( - $item['id'], + (int) $item['id'], true, false, false, diff --git a/public/main/inc/lib/sessionmanager.lib.php b/public/main/inc/lib/sessionmanager.lib.php index 17e4f3ffd1..074dfaa439 100644 --- a/public/main/inc/lib/sessionmanager.lib.php +++ b/public/main/inc/lib/sessionmanager.lib.php @@ -4592,6 +4592,7 @@ class SessionManager * @param bool $copyTeachersAndDrh * @param bool $create_new_courses New courses will be created * @param bool $set_exercises_lp_invisible Set exercises and LPs in the new session to invisible by default + * @param bool $copyWithSessionContent Copy course session content into the courses * * @return int The new session ID on success, 0 otherwise * @@ -4600,11 +4601,12 @@ class SessionManager * @todo make sure the extra session fields are copied too */ public static function copy( - $id, - $copy_courses = true, - $copyTeachersAndDrh = true, - $create_new_courses = false, - $set_exercises_lp_invisible = false + int $id, + bool $copy_courses = true, + bool $copyTeachersAndDrh = true, + bool $create_new_courses = false, + bool $set_exercises_lp_invisible = false, + bool $copyWithSessionContent = false, ) { $id = (int) $id; $s = self::fetch($id); @@ -4714,9 +4716,7 @@ class SessionManager foreach ($short_courses as $course_data) { $course = CourseManager::copy_course_simple( - $course_data['title'].' '.get_lang( - 'Copy' - ), + $course_data['title'].' '.get_lang('Copy'), $course_data['course_code'], $id, $sid, @@ -4765,6 +4765,20 @@ class SessionManager $short_courses = $new_short_courses; self::add_courses_to_session($sid, $short_courses, true); + if ($copyWithSessionContent) { + foreach ($courses as $course) { + CourseManager::copy_course( + $course['code'], + $id, + $course['code'], + $sid, + [], + false, + true + ); + } + } + if (false === $create_new_courses && $copyTeachersAndDrh) { foreach ($short_courses as $courseItemId) { $coachList = self::getCoachesByCourseSession($id, $courseItemId); diff --git a/public/main/session/session_list.php b/public/main/session/session_list.php index 1ebe175b83..d6d9fb96a2 100644 --- a/public/main/session/session_list.php +++ b/public/main/session/session_list.php @@ -20,7 +20,12 @@ $action = $_REQUEST['action'] ?? null; $idChecked = $_REQUEST['idChecked'] ?? null; $idMultiple = $_REQUEST['id'] ?? null; $listType = isset($_REQUEST['list_type']) ? Security::remove_XSS($_REQUEST['list_type']) : SessionManager::getDefaultSessionTab(); -$copySessionContent = isset($_REQUEST['copy_session_content']) ? true : false; +$copySessionContent = isset($_REQUEST['copy_session_content']); +$addSessionContent = 'true' === api_get_setting('session.duplicate_specific_session_content_on_session_copy'); + +if (!$addSessionContent) { + $copySessionContent = false; +} switch ($action) { case 'delete_multiple': @@ -50,7 +55,14 @@ switch ($action) { header('Location: '.$url); exit(); case 'copy': - $result = SessionManager::copy($idChecked); + $result = SessionManager::copy( + (int) $idChecked, + true, + true, + false, + false, + $copySessionContent + ); if ($result) { Display::addFlash(Display::return_message(get_lang('ItemCopied'))); } else { @@ -65,7 +77,7 @@ switch ($action) { case 'copy_multiple': $sessionList = explode(',', $idMultiple); foreach ($sessionList as $id) { - $sessionIdCopied = SessionManager::copy($id); + $sessionIdCopied = SessionManager::copy((int) $id); if ($sessionIdCopied) { $sessionInfo = api_get_session_info($sessionIdCopied); Display::addFlash(Display::return_message(get_lang('ItemCopied').' - '.$sessionInfo['name'])); @@ -152,14 +164,38 @@ if (isset($_REQUEST['keyword'])) { $filter->groupOp = 'OR'; $filter = json_encode($filter); - $url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_sessions&_force_search=true&rows=20&page=1&sidx=&sord=asc&filters='.$filter.'&searchField=s.title&searchString='.Security::remove_XSS($_REQUEST['keyword']).'&searchOper=in'; + $url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?' + .http_build_query([ + 'a' => 'get_sessions', + '_force_search' => 'true', + 'rows' => 20, + 'page' => 1, + 'sidx' => '', + 'sord' => 'asc', + 'filters' => $filter, + 'searchField' => 's.title', + 'searchString' => Security::remove_XSS($_REQUEST['keyword']), + 'searchOper' => 'in', + ]); } if (isset($_REQUEST['id_category'])) { $sessionCategory = SessionManager::get_session_category($_REQUEST['id_category']); if (!empty($sessionCategory)) { //Begin with see the searchOper param - $url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_sessions&_force_search=true&rows=20&page=1&sidx=&sord=asc&filters=&searchField=sc.title&searchString='.Security::remove_XSS($sessionCategory['title']).'&searchOper=in'; + $url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?' + .http_build_query([ + 'a' => 'get_sessions', + '_force_search' => 'true', + 'rows' => 20, + 'page' => 1, + 'sidx' => '', + 'sord' => 'asc', + 'filters' => '', + 'searchField' => 'sc.title', + 'searchString' => Security::remove_XSS($sessionCategory['title']), + 'searchOper' => 'in', + ]); } } @@ -187,6 +223,11 @@ if (!isset($_GET['keyword'])) { } $hideSearch = ('true' === api_get_setting('session.hide_search_form_in_session_list')); +$copySessionContentLink = ''; +if ($addSessionContent) { + $copySessionContentLink = ' '. + Display::return_icon('copy.png', get_lang('CopyWithSessionContent'), '', ICON_SIZE_SMALL).''; +} //With this function we can add actions to the jgrid (edit, delete, etc) $action_links = 'function action_formatter(cellvalue, options, rowObject) { @@ -194,6 +235,7 @@ $action_links = 'function action_formatter(cellvalue, options, rowObject) { ' '.Display::getMdiIcon('account-multiple-plus', 'ch-tool-icon', null, 22, get_lang('Subscribe users to this session')).''. ' '.Display::getMdiIcon('book-open-page-variant', 'ch-tool-icon', null, 22, get_lang('Add courses to this session')).''. ' '.Display::getMdiIcon('text-box-plus', 'ch-tool-icon', null, 22, get_lang('Copy')).''. + $copySessionContentLink. ''. '\'; }'; diff --git a/src/CoreBundle/Settings/SessionSettingsSchema.php b/src/CoreBundle/Settings/SessionSettingsSchema.php index d5f2da7dbc..afea86fc27 100644 --- a/src/CoreBundle/Settings/SessionSettingsSchema.php +++ b/src/CoreBundle/Settings/SessionSettingsSchema.php @@ -79,6 +79,7 @@ class SessionSettingsSchema extends AbstractSettingsSchema 'session_creation_user_course_extra_field_relation_to_prefill' => '', 'session_creation_form_set_extra_fields_mandatory' => '', 'session_model_list_field_ordered_by_id' => 'false', + 'duplicate_specific_session_content_on_session_copy' => 'false', ] ) ; @@ -217,6 +218,7 @@ class SessionSettingsSchema extends AbstractSettingsSchema ] ) ->add('session_model_list_field_ordered_by_id', YesNoType::class) + ->add('duplicate_specific_session_content_on_session_copy', YesNoType::class) ; $this->updateFormFieldsFromSettingsInfo($builder); diff --git a/src/CourseBundle/Component/CourseCopy/CourseRestorer.php b/src/CourseBundle/Component/CourseCopy/CourseRestorer.php index a9379dc78d..675d0bbd50 100644 --- a/src/CourseBundle/Component/CourseCopy/CourseRestorer.php +++ b/src/CourseBundle/Component/CourseCopy/CourseRestorer.php @@ -80,6 +80,7 @@ class CourseRestorer */ public $add_text_in_items = false; public $destination_course_id; + public bool $copySessionContent = false; /** * CourseRestorer constructor. @@ -392,7 +393,7 @@ class CourseRestorer $groupInfo = $this->checkGroupId($groupId); // if folder exists then just refresh it - api_item_property_update( + /*api_item_property_update( $course_info, TOOL_DOCUMENT, $documentData, @@ -403,12 +404,13 @@ class CourseRestorer null, null, $my_session_id - ); + );*/ } } } elseif (DOCUMENT == $document->file_type) { // Checking if folder exists in the database otherwise we created it $dir_to_create = dirname($document->path); + $originalFolderNameList[basename($document->path)] = $document->title; if (!empty($dir_to_create) && 'document' != $dir_to_create && '/' != $dir_to_create) { if (is_dir($path.dirname($document->path))) { $sql = "SELECT id FROM $table @@ -510,7 +512,7 @@ class CourseRestorer $toUserId = $this->checkUserId($toUserId, true); $groupInfo = $this->checkGroupId($toGroupId); - api_item_property_update( + /*api_item_property_update( $course_info, TOOL_DOCUMENT, $document_id, @@ -521,7 +523,7 @@ class CourseRestorer null, null, $my_session_id - ); + );*/ } else { $obj = Database::fetch_object($res); $document_id = $obj->id; @@ -557,7 +559,7 @@ class CourseRestorer $toUserId = $this->checkUserId($toUserId, true); $groupInfo = $this->checkGroupId($toGroupId); - api_item_property_update( + /*api_item_property_update( $course_info, TOOL_DOCUMENT, $obj->id, @@ -568,7 +570,7 @@ class CourseRestorer null, null, $my_session_id - ); + );*/ } // Replace old course code with the new destination code @@ -637,6 +639,7 @@ class CourseRestorer } if (!empty($session_id)) { + $originalPath = $document->path; $document_path = explode('/', $document->path, 3); $course_path = $path; $orig_base_folder = $document_path[1]; @@ -658,12 +661,14 @@ class CourseRestorer if ($folder_exists) { // e.g: carpeta1 in session $_SESSION['orig_base_foldername'] = $new_base_foldername; - $x = ''; + $x = 0; while ($folder_exists) { $x++; $new_base_foldername = $document_path[1].'_'.$x; $new_base_path = $orig_base_path.'_'.$x; - if ($_SESSION['new_base_foldername'] == $new_base_foldername) { + if (isset($_SESSION['new_base_foldername']) + && $_SESSION['new_base_foldername'] == $new_base_foldername + ) { break; } $folder_exists = file_exists($new_base_path); @@ -749,7 +754,7 @@ class CourseRestorer $toUserId = $this->checkUserId($toUserId, true); $groupInfo = $this->checkGroupId($toGroupId); - api_item_property_update( + /*api_item_property_update( $course_info, TOOL_DOCUMENT, $document_id, @@ -760,7 +765,7 @@ class CourseRestorer null, null, $my_session_id - ); + );*/ } } else { if (file_exists($path.$document->path)) { @@ -813,7 +818,7 @@ class CourseRestorer $toUserId = $this->checkUserId($toUserId, true); $groupInfo = $this->checkGroupId($toGroupId); - api_item_property_update( + /*api_item_property_update( $course_info, TOOL_DOCUMENT, $document_id, @@ -824,7 +829,7 @@ class CourseRestorer null, null, $my_session_id - ); + );*/ } } } else { @@ -879,7 +884,7 @@ class CourseRestorer $toUserId = $this->checkUserId($toUserId, true); $groupInfo = $this->checkGroupId($toGroupId); - api_item_property_update( + /*api_item_property_update( $course_info, TOOL_DOCUMENT, $document_id, @@ -890,7 +895,7 @@ class CourseRestorer null, null, $my_session_id - ); + );*/ } } @@ -957,7 +962,7 @@ class CourseRestorer $toUserId = $this->checkUserId($toUserId, true); $groupInfo = $this->checkGroupId($toGroupId); - api_item_property_update( + /*api_item_property_update( $course_info, TOOL_DOCUMENT, $document_id, @@ -968,7 +973,7 @@ class CourseRestorer null, null, $my_session_id - ); + );*/ } } else { // There was an error in checking existence and @@ -1116,10 +1121,7 @@ class CourseRestorer if (isset($this->course->resources[RESOURCE_FORUMCATEGORY]) && isset($this->course->resources[RESOURCE_FORUMCATEGORY][$params['forum_category']])) { if (-1 == $this->course->resources[RESOURCE_FORUMCATEGORY][$params['forum_category']]->destination_id) { - $cat_id = $this->restore_forum_category( - $params['forum_category'], - $sessionId - ); + $cat_id = $this->restore_forum_category($params['forum_category'], $sessionId); } else { $cat_id = $this->course->resources[RESOURCE_FORUMCATEGORY][$params['forum_category']]->destination_id; } @@ -1157,13 +1159,13 @@ class CourseRestorer $sql = "UPDATE $table_forum SET forum_id = iid WHERE iid = $new_id"; Database::query($sql); - api_item_property_update( + /*api_item_property_update( $this->destination_course_info, TOOL_FORUM, $new_id, 'ForumUpdated', api_get_user_id() - ); + );*/ $this->course->resources[RESOURCE_FORUM][$id]->destination_id = $new_id; @@ -1224,13 +1226,13 @@ class CourseRestorer $sql = "UPDATE $forum_cat_table SET cat_id = iid WHERE iid = $new_id"; Database::query($sql); - api_item_property_update( + /*api_item_property_update( $this->destination_course_info, TOOL_FORUM_CATEGORY, $new_id, 'ForumCategoryUpdated', api_get_user_id() - ); + );*/ $this->course->resources[RESOURCE_FORUMCATEGORY][$id]->destination_id = $new_id; } @@ -1276,7 +1278,7 @@ class CourseRestorer $sql = "UPDATE $table SET thread_id = iid WHERE iid = $new_id"; Database::query($sql); - api_item_property_update( + /*api_item_property_update( $this->destination_course_info, TOOL_FORUM_THREAD, $new_id, @@ -1287,7 +1289,7 @@ class CourseRestorer null, null, $sessionId - ); + );*/ $this->course->resources[RESOURCE_FORUMTOPIC][$thread_id]->destination_id = $new_id; foreach ($this->course->resources[RESOURCE_FORUMPOST] as $post_id => $post) { @@ -1335,7 +1337,7 @@ class CourseRestorer $sql = "UPDATE $table_post SET post_id = iid WHERE iid = $new_id"; Database::query($sql); - api_item_property_update( + /*api_item_property_update( $this->destination_course_info, TOOL_FORUM_POST, $new_id, @@ -1346,7 +1348,7 @@ class CourseRestorer null, null, $sessionId - ); + );*/ $this->course->resources[RESOURCE_FORUMPOST][$id]->destination_id = $new_id; } @@ -1363,15 +1365,12 @@ class CourseRestorer $resources = $this->course->resources; foreach ($resources[RESOURCE_LINK] as $oldLinkId => $link) { - $cat_id = $this->restore_link_category( - $link->category_id, - $session_id - ); + $cat_id = (int) $this->restore_link_category($link->category_id, $session_id); $sql = "SELECT MAX(display_order) FROM $link_table WHERE c_id = ".$this->destination_course_id." AND - category_id='".(int) $cat_id."'"; + category_id='".$cat_id."'"; $result = Database::query($sql); list($max_order) = Database::fetch_array($result); @@ -1395,13 +1394,13 @@ class CourseRestorer $sql = "UPDATE $link_table SET id = iid WHERE iid = $id"; Database::query($sql); - api_item_property_update( + /*api_item_property_update( $this->destination_course_info, TOOL_LINK, $id, 'LinkAdded', api_get_user_id() - ); + );*/ if (!isset($this->course->resources[RESOURCE_LINK][$oldLinkId])) { $this->course->resources[RESOURCE_LINK][$oldLinkId] = new stdClass(); @@ -1454,13 +1453,13 @@ class CourseRestorer Database::query($sql); $courseInfo = api_get_course_info_by_id($this->destination_course_id); - api_item_property_update( + /*api_item_property_update( $courseInfo, TOOL_LINK_CATEGORY, $new_id, 'LinkCategoryAdded', api_get_user_id() - ); + );*/ api_set_default_visibility( $new_id, TOOL_LINK_CATEGORY, @@ -1489,11 +1488,13 @@ class CourseRestorer $tool_intro_table = Database::get_course_table(TABLE_TOOL_INTRO); $resources = $this->course->resources; foreach ($resources[RESOURCE_TOOL_INTRO] as $id => $tool_intro) { - $sql = "DELETE FROM $tool_intro_table + if (!$this->copySessionContent) { + $sql = "DELETE FROM $tool_intro_table WHERE c_id = ".$this->destination_course_id." AND id='".self::DBUTF8escapestring($tool_intro->id)."'"; - Database::query($sql); + Database::query($sql); + } $tool_intro->intro_text = DocumentManager::replaceUrlWithNewCourseCode( $tool_intro->intro_text, @@ -2862,7 +2863,7 @@ class CourseRestorer $extraFieldValue->save($params); } } - api_item_property_update( + /*api_item_property_update( $this->destination_course_info, TOOL_LEARNPATH, $new_lp_id, @@ -2873,10 +2874,10 @@ class CourseRestorer 0, 0, $session_id - ); + );*/ // Set the new LP to visible - api_item_property_update( + /*api_item_property_update( $this->destination_course_info, TOOL_LEARNPATH, $new_lp_id, @@ -2887,7 +2888,7 @@ class CourseRestorer 0, 0, $session_id - ); + );*/ $new_item_ids = []; $parent_item_ids = []; @@ -2904,7 +2905,7 @@ class CourseRestorer // Dealing with path the same way as ref as some data has // been put into path when it's a local resource // Only fix the path for no scos - if ('sco' == $item['item_type']) { + if ('sco' === $item['item_type']) { $path = $item['path']; } else { $path = $this->get_new_id($item['item_type'], $item['path']); @@ -3121,13 +3122,13 @@ class CourseRestorer $sql = "UPDATE $table_glossary SET glossary_id = iid WHERE iid = $my_id"; Database::query($sql); - api_item_property_update( + /*api_item_property_update( $this->destination_course_info, TOOL_GLOSSARY, $my_id, 'GlossaryAdded', api_get_user_id() - ); + );*/ if (!isset($this->course->resources[RESOURCE_GLOSSARY][$id])) { $this->course->resources[RESOURCE_GLOSSARY][$id] = new stdClass(); @@ -3255,13 +3256,13 @@ class CourseRestorer $sql = "UPDATE $table_thematic SET id = iid WHERE iid = $last_id"; Database::query($sql); - api_item_property_update( + /*api_item_property_update( $this->destination_course_info, 'thematic', $last_id, 'ThematicAdded', api_get_user_id() - ); + );*/ foreach ($thematic->thematic_advance_list as $thematic_advance) { unset($thematic_advance['id']); @@ -3280,13 +3281,13 @@ class CourseRestorer $sql = "UPDATE $table_thematic_advance SET id = iid WHERE iid = $my_id"; Database::query($sql); - api_item_property_update( + /*api_item_property_update( $this->destination_course_info, 'thematic_advance', $my_id, 'ThematicAdvanceAdded', api_get_user_id() - ); + );*/ } } @@ -3301,13 +3302,13 @@ class CourseRestorer $sql = "UPDATE $table_thematic_plan SET id = iid WHERE iid = $my_id"; Database::query($sql); - api_item_property_update( + /*api_item_property_update( $this->destination_course_info, 'thematic_plan', $my_id, 'ThematicPlanAdded', api_get_user_id() - ); + );*/ } } } @@ -3348,13 +3349,13 @@ class CourseRestorer $this->course->resources[RESOURCE_ATTENDANCE][$id]->destination_id = $last_id; - api_item_property_update( + /*api_item_property_update( $this->destination_course_info, TOOL_ATTENDANCE, $last_id, 'AttendanceAdded', api_get_user_id() - ); + );*/ foreach ($obj->attendance_calendar as $attendance_calendar) { unset($attendance_calendar['id']);