diff --git a/main/admin/course_edit.php b/main/admin/course_edit.php index 49eecb54946..5be43554488 100755 --- a/main/admin/course_edit.php +++ b/main/admin/course_edit.php @@ -186,7 +186,7 @@ $courseTeacherNames = []; foreach ($course_teachers as $courseTeacherId) { /** @var User $courseTeacher */ - $courseTeacher = UserManager::getRepository()->find($courseTeacherId); + $courseTeacher = api_get_user_entity($courseTeacherId); $courseTeacherNames[$courseTeacher->getId()] = UserManager::formatUserFullName($courseTeacher, true); } diff --git a/main/auth/profile.php b/main/auth/profile.php index 23e6e29811d..9c3b57f78e2 100755 --- a/main/auth/profile.php +++ b/main/auth/profile.php @@ -400,8 +400,7 @@ function show_image(image,width,height) { $wrong_current_password = false; $user_data = $form->getSubmitValues(1); - /** @var User $user */ - $user = UserManager::getRepository()->find(api_get_user_id()); + $user = api_get_user_entity(); // set password if a new one was provided $validPassword = false; @@ -664,7 +663,7 @@ function show_image(image,width,height) { if ($hook) { Database::getManager()->clear(User::class); // Avoid cache issue (user entity is used before) - $user = api_get_user_entity(api_get_user_id()); // Get updated user info for hook event + $user = api_get_user_entity(); // Get updated user info for hook event $hook->setEventData(['user' => $user]); $hook->notifyUpdateUser(HOOK_EVENT_TYPE_POST); } diff --git a/main/course_home/course_home.php b/main/course_home/course_home.php index 1809c13cddc..485171c9d20 100755 --- a/main/course_home/course_home.php +++ b/main/course_home/course_home.php @@ -241,7 +241,7 @@ function buttonForAllShowHide() /** * @var Chamilo\UserBundle\Entity\User */ - $user = UserManager::getRepository()->find(api_get_user_id()); + $user = api_get_user_entity(); if ($user) { foreach ($user->getCurrentlyAccessibleSessions() as $session) { $redirectionTarget = api_get_self().'?id_session='.$session->getId(); @@ -253,7 +253,7 @@ function buttonForAllShowHide() /** * @var Chamilo\UserBundle\Entity\User */ - $user = UserManager::getRepository()->find(api_get_user_id()); + $user = api_get_user_entity(); if ($user && !$user->getCurrentlyAccessibleSessions()) { // subscription was probably refused because user session expired, go back to page "about" $redirectionTarget = api_get_path(WEB_PATH).'course/'.$courseId.'/about'; diff --git a/main/cron/import_csv.php b/main/cron/import_csv.php index eece6915bbf..f09fe064d84 100755 --- a/main/cron/import_csv.php +++ b/main/cron/import_csv.php @@ -1286,7 +1286,7 @@ private function importCalendarStatic($file, $moveFile = true) ]; /** @var CItemProperty $itemProperty */ $itemProperty = $em->getRepository('ChamiloCourseBundle:CItemProperty')->findOneBy($criteria); - $courseEntity = $em->getRepository('ChamiloCoreBundle:Course')->find($courseInfo['real_id']); + $courseEntity = api_get_course_entity($courseInfo['real_id']); if ($itemProperty && $courseEntity) { $itemProperty->setCourse($courseEntity); $em->persist($itemProperty); diff --git a/main/cron/user_import/resend_email_with_new_password.php b/main/cron/user_import/resend_email_with_new_password.php index 8854b17fa48..791681e7e8c 100755 --- a/main/cron/user_import/resend_email_with_new_password.php +++ b/main/cron/user_import/resend_email_with_new_password.php @@ -44,8 +44,7 @@ $pass = api_substr($row['username'], 0, 4).rand(0, 9).rand(0, 9); if ($user) { - /** @var User $user */ - $user = $repository->find($row['user_id']); + $user = api_get_user_entity($row['user_id']); $user->setPlainPassword($pass); $userManager->updateUser($user, true); } else { diff --git a/main/inc/ajax/skill.ajax.php b/main/inc/ajax/skill.ajax.php index 0e672456c7c..610ef01fa3d 100755 --- a/main/inc/ajax/skill.ajax.php +++ b/main/inc/ajax/skill.ajax.php @@ -420,7 +420,7 @@ exit; } - $session = $em->getRepository('ChamiloCoreBundle:Session')->find($sessionId); + $session = api_get_session_entity($sessionId); /** @var \Chamilo\SkillBundle\Entity\SkillRelItem $skillRelItem */ $skillRelItem = $em->getRepository('ChamiloSkillBundle:SkillRelItem')->findOneBy( ['itemId' => $itemId, 'itemType' => $typeId, 'skill' => $skillId] @@ -498,7 +498,7 @@ $course = api_get_course_entity($courseId); $skillUser->setCourse($course); if (!empty($sessionId)) { - $session = $em->getRepository('ChamiloCoreBundle:Session')->find($sessionId); + $session = api_get_session_entity($sessionId); $skillUser->setSession($session); } diff --git a/main/inc/lib/add_course.lib.inc.php b/main/inc/lib/add_course.lib.inc.php index d553779dfcb..9d8538374c0 100755 --- a/main/inc/lib/add_course.lib.inc.php +++ b/main/inc/lib/add_course.lib.inc.php @@ -1,7 +1,10 @@ \n\n \n \n Not authorized\n \n \n \n"; - $cp = api_get_path(SYS_COURSE_PATH).$course_repository; - - //Creating document folder - mkdir($cp, $perm); - mkdir($cp.'/document', $perm); - $cpt = $cp.'/document/index.html'; - $fd = fopen($cpt, 'w'); - fwrite($fd, $htmlpage); - fclose($fd); - - /* - @chmod($cpt, $perm_file); - @copy($cpt, $cp . '/document/index.html'); - mkdir($cp . '/document/images', $perm); - @copy($cpt, $cp . '/document/images/index.html'); - mkdir($cp . '/document/images/gallery/', $perm); - @copy($cpt, $cp . '/document/images/gallery/index.html'); - mkdir($cp . '/document/shared_folder/', $perm); - @copy($cpt, $cp . '/document/shared_folder/index.html'); - mkdir($cp . '/document/audio', $perm); - @copy($cpt, $cp . '/document/audio/index.html'); - mkdir($cp . '/document/flash', $perm); - @copy($cpt, $cp . '/document/flash/index.html'); - mkdir($cp . '/document/video', $perm); - @copy($cpt, $cp . '/document/video/index.html'); */ - - //Creatind dropbox folder - mkdir($cp.'/dropbox', $perm); - $cpt = $cp.'/dropbox/index.html'; - $fd = fopen($cpt, 'w'); - fwrite($fd, $htmlpage); - fclose($fd); - @chmod($cpt, $perm_file); - mkdir($cp.'/group', $perm); - @copy($cpt, $cp.'/group/index.html'); - mkdir($cp.'/page', $perm); - @copy($cpt, $cp.'/page/index.html'); - mkdir($cp.'/scorm', $perm); - @copy($cpt, $cp.'/scorm/index.html'); - mkdir($cp.'/upload', $perm); - @copy($cpt, $cp.'/upload/index.html'); - mkdir($cp.'/upload/forum', $perm); - @copy($cpt, $cp.'/upload/forum/index.html'); - mkdir($cp.'/upload/forum/images', $perm); - @copy($cpt, $cp.'/upload/forum/images/index.html'); - mkdir($cp.'/upload/test', $perm); - @copy($cpt, $cp.'/upload/test/index.html'); - mkdir($cp.'/upload/blog', $perm); - @copy($cpt, $cp.'/upload/blog/index.html'); - mkdir($cp.'/upload/learning_path', $perm); - @copy($cpt, $cp.'/upload/learning_path/index.html'); - mkdir($cp.'/upload/learning_path/images', $perm); - @copy($cpt, $cp.'/upload/learning_path/images/index.html'); - mkdir($cp.'/upload/calendar', $perm); - @copy($cpt, $cp.'/upload/calendar/index.html'); - mkdir($cp.'/upload/calendar/images', $perm); - @copy($cpt, $cp.'/upload/calendar/images/index.html'); - mkdir($cp.'/work', $perm); - @copy($cpt, $cp.'/work/index.html'); - mkdir($cp.'/upload/announcements', $perm); - @copy($cpt, $cp.'/upload/announcements/index.html'); - mkdir($cp.'/upload/announcements/images', $perm); - @copy($cpt, $cp.'/upload/announcements/images/index.html'); - - //Oral expression question type - mkdir($cp.'/exercises', $perm); - @copy($cpt, $cp.'/exercises/index.html'); - - // Create .htaccess in the dropbox directory. - $fp = fopen($cp.'/dropbox/.htaccess', 'w'); - fwrite( - $fp, - "AuthName AllowLocalAccess - AuthType Basic - - order deny,allow - deny from all - - php_flag zlib.output_compression off" - ); - fclose($fp); - - // Build index.php of the course. - /*$fd = fopen($cp . '/index.php', 'w'); - - // str_replace() removes \r that cause squares to appear at the end of each line - //@todo fix the harcoded include - $string = str_replace( - "\r", - "", - "" - ); - fwrite($fd, $string); - @chmod($cp . '/index.php', $perm_file);*/ - return 0; - } - /** * Gets an array with all the course tables (deprecated?). * @@ -430,204 +317,11 @@ public static function fill_db_course( $courseInfo = api_get_course_info_by_id($course_id); $authorId = empty($authorId) ? api_get_user_id() : (int) $authorId; - $tbl_course_homepage = Database::get_course_table(TABLE_TOOL_LIST); $TABLEGROUPCATEGORIES = Database::get_course_table(TABLE_GROUP_CATEGORY); $TABLEITEMPROPERTY = Database::get_course_table(TABLE_ITEM_PROPERTY); $TABLETOOLDOCUMENT = Database::get_course_table(TABLE_DOCUMENT); - $TABLESETTING = Database::get_course_table(TABLE_COURSE_SETTING); $TABLEGRADEBOOK = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY); $TABLEGRADEBOOKLINK = Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINK); - $visible_for_course_admin = 0; - /* Course tools */ - Database::query( - "INSERT INTO $tbl_course_homepage (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id) - VALUES ($course_id, 1, '".TOOL_COURSE_DESCRIPTION."','course_description/index.php','info.gif','".self::string2binary( - api_get_setting( - 'course_create_active_tools', - 'course_description' - ) - )."','0','squaregrey.gif', 0,'_self','authoring','0')" - ); - Database::query( - "INSERT INTO $tbl_course_homepage (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id) - VALUES ($course_id, 2, '".TOOL_CALENDAR_EVENT."','calendar/agenda.php','agenda.gif','".self::string2binary( - api_get_setting('course_create_active_tools', 'agenda') - )."','0','squaregrey.gif',0,'_self','interaction','0')" - ); - Database::query( - "INSERT INTO $tbl_course_homepage (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id) - VALUES ($course_id, 3, '".TOOL_DOCUMENT."','document/document.php','folder_document.gif','".self::string2binary( - api_get_setting('course_create_active_tools', 'documents') - )."','0','squaregrey.gif',0,'_self','authoring','0')" - ); - Database::query( - "INSERT INTO $tbl_course_homepage (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id) - VALUES ($course_id, 4, '".TOOL_LEARNPATH."','lp/lp_controller.php','scorms.gif','".self::string2binary( - api_get_setting('course_create_active_tools', 'learning_path') - )."','0','squaregrey.gif',0,'_self','authoring','0')" - ); - Database::query( - "INSERT INTO $tbl_course_homepage (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id) - VALUES ($course_id, 5, '".TOOL_LINK."','link/link.php','links.gif','".self::string2binary( - api_get_setting('course_create_active_tools', 'links') - )."','0','squaregrey.gif',0,'_self','authoring','0')" - ); - Database::query( - "INSERT INTO $tbl_course_homepage (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id) - VALUES ($course_id, 6, '".TOOL_QUIZ."','exercise/exercise.php','quiz.gif','".self::string2binary( - api_get_setting('course_create_active_tools', 'quiz') - )."','0','squaregrey.gif',0,'_self','authoring','0')" - ); - Database::query( - "INSERT INTO $tbl_course_homepage (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id) - VALUES ($course_id, 7, '".TOOL_ANNOUNCEMENT."','announcements/announcements.php','valves.gif','".self::string2binary( - api_get_setting('course_create_active_tools', 'announcements') - )."','0','squaregrey.gif', 0,'_self','authoring','0')" - ); - Database::query( - "INSERT INTO $tbl_course_homepage (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id) - VALUES ($course_id, 8, '".TOOL_FORUM."','forum/index.php','forum.gif','".self::string2binary( - api_get_setting('course_create_active_tools', 'forums') - )."','0','squaregrey.gif',0,'_self','interaction','0')" - ); - Database::query( - "INSERT INTO $tbl_course_homepage (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id) - VALUES ($course_id, 9, '".TOOL_DROPBOX."','dropbox/index.php','dropbox.gif','".self::string2binary( - api_get_setting('course_create_active_tools', 'dropbox') - )."','0','squaregrey.gif',0,'_self','interaction','0')" - ); - Database::query( - "INSERT INTO $tbl_course_homepage (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id) - VALUES ($course_id, 10, '".TOOL_USER."','user/user.php','members.gif','".self::string2binary( - api_get_setting('course_create_active_tools', 'users') - )."','0','squaregrey.gif',0,'_self','interaction','0')" - ); - Database::query( - "INSERT INTO $tbl_course_homepage (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id) - VALUES ($course_id, 11, '".TOOL_GROUP."','group/group.php','group.gif','".self::string2binary( - api_get_setting('course_create_active_tools', 'groups') - )."','0','squaregrey.gif',0,'_self','interaction','0')" - ); - Database::query( - "INSERT INTO $tbl_course_homepage (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id) - VALUES ($course_id, 12, '".TOOL_CHAT."','chat/chat.php','chat.gif','".self::string2binary( - api_get_setting('course_create_active_tools', 'chat') - )."','0','squaregrey.gif',0,'_self','interaction','0')" - ); - Database::query( - "INSERT INTO $tbl_course_homepage (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id) - VALUES ($course_id, 13, '".TOOL_STUDENTPUBLICATION."','work/work.php','works.gif','".self::string2binary( - api_get_setting( - 'course_create_active_tools', - 'student_publications' - ) - )."','0','squaregrey.gif',0,'_self','interaction','0')" - ); - Database::query( - "INSERT INTO $tbl_course_homepage (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id) - VALUES ($course_id, 14, '".TOOL_SURVEY."','survey/survey_list.php','survey.gif','".self::string2binary( - api_get_setting('course_create_active_tools', 'survey') - )."','0','squaregrey.gif',0,'_self','interaction','0')" - ); - Database::query( - "INSERT INTO $tbl_course_homepage (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id) - VALUES ($course_id, 15, '".TOOL_WIKI."','wiki/index.php','wiki.gif','".self::string2binary( - api_get_setting('course_create_active_tools', 'wiki') - )."','0','squaregrey.gif',0,'_self','interaction','0')" - ); - Database::query( - "INSERT INTO $tbl_course_homepage (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id) - VALUES ($course_id, 16, '".TOOL_GRADEBOOK."','gradebook/index.php','gradebook.gif','".self::string2binary( - api_get_setting('course_create_active_tools', 'gradebook') - )."','0','squaregrey.gif',0,'_self','authoring','0')" - ); - Database::query( - "INSERT INTO $tbl_course_homepage (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id) - VALUES ($course_id, 17, '".TOOL_GLOSSARY."','glossary/index.php','glossary.gif','".self::string2binary( - api_get_setting('course_create_active_tools', 'glossary') - )."','0','squaregrey.gif',0,'_self','authoring','0')" - ); - Database::query( - "INSERT INTO $tbl_course_homepage (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id) - VALUES ($course_id, 18, '".TOOL_NOTEBOOK."','notebook/index.php','notebook.gif','".self::string2binary( - api_get_setting('course_create_active_tools', 'notebook') - )."','0','squaregrey.gif',0,'_self','interaction','0')" - ); - if (api_get_configuration_value('allow_portfolio_tool')) { - $tId = Database::insert( - $tbl_course_homepage, - [ - 'c_id' => $course_id, - 'name' => 'portfolio', - 'link' => 'portfolio/index.php', - 'image' => 'wiki_task.png', - 'visibility' => api_get_setting('course_create_active_tools', 'portfolio') == 'true' ? 1 : 0, - 'admin' => 0, - 'address' => 'squaregrey.gif', - 'added_tool' => 0, - 'target' => '_self', - 'category' => 'interaction', - 'session_id' => 0, - ] - ); - Database::update( - $tbl_course_homepage, - ['id' => $tId], - ['iid = ?' => $tId] - ); - } - - $setting = intval(self::string2binary( - api_get_setting('course_create_active_tools', 'attendances') - )); - - Database::query( - "INSERT INTO $tbl_course_homepage (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id) - VALUES ($course_id, 19, '".TOOL_ATTENDANCE."','attendance/index.php','attendance.gif','".$setting."','0','squaregrey.gif',0,'_self','authoring','0')" - ); - - $setting = intval(self::string2binary( - api_get_setting('course_create_active_tools', 'course_progress') - )); - - Database::query( - "INSERT INTO $tbl_course_homepage (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id) - VALUES ($course_id, 20, '".TOOL_COURSE_PROGRESS."','course_progress/index.php','course_progress.gif','".$setting."','0','squaregrey.gif',0,'_self','authoring','0')" - ); - - if (api_get_setting('search_enabled') === 'true') { - Database::query( - "INSERT INTO $tbl_course_homepage (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id) - VALUES ($course_id, 23, '".TOOL_SEARCH."','search/','info.gif','".self::string2binary( - api_get_setting( - 'course_create_active_tools', - 'enable_search' - ) - )."','0','search.gif',0,'_self','authoring','0')" - ); - } - - $sql = "INSERT INTO $tbl_course_homepage (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id) - VALUES ($course_id, 24,'".TOOL_BLOGS."','blog/blog_admin.php','blog_admin.gif','".intval( - self::string2binary( - api_get_setting('course_create_active_tools', 'blogs') - ) - )."','1','squaregrey.gif',0,'_self','admin','0')"; - Database::query($sql); - - /* Course homepage tools for course admin only */ - Database::query( - "INSERT INTO $tbl_course_homepage (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id) - VALUES ($course_id, 25, '".TOOL_TRACKING."','tracking/courseLog.php','statistics.gif','$visible_for_course_admin','1','', 0,'_self','admin','0')" - ); - Database::query( - "INSERT INTO $tbl_course_homepage (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id) - VALUES ($course_id, 26, '".TOOL_COURSE_SETTING."','course_info/infocours.php','reference.gif','$visible_for_course_admin','1','', 0,'_self','admin','0')" - ); - Database::query( - "INSERT INTO $tbl_course_homepage (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id) - VALUES ($course_id, 27, '".TOOL_COURSE_MAINTENANCE."','course_info/maintenance.php','backup.gif','$visible_for_course_admin','1','',0,'_self', 'admin','0')" - ); $alert = api_get_setting('email_alert_manager_on_new_quiz'); if ($alert === 'true') { @@ -636,46 +330,6 @@ public static function fill_db_course( $defaultEmailExerciseAlert = 0; } - /* course_setting table (courseinfo tool) */ - $settings = [ - 'email_alert_manager_on_new_doc' => ['title' => '', 'default' => 0, 'category' => 'work'], - 'email_alert_on_new_doc_dropbox' => ['default' => 0, 'category' => 'dropbox'], - 'allow_user_edit_agenda' => ['default' => 0, 'category' => 'agenda'], - 'allow_user_edit_announcement' => ['default' => 0, 'category' => 'announcement'], - 'email_alert_manager_on_new_quiz' => ['default' => $defaultEmailExerciseAlert, 'category' => 'quiz'], - 'allow_user_image_forum' => ['default' => 1, 'category' => 'forum'], - 'course_theme' => ['default' => '', 'category' => 'theme'], - 'allow_learning_path_theme' => ['default' => 1, 'category' => 'theme'], - 'allow_open_chat_window' => ['default' => 1, 'category' => 'chat'], - 'email_alert_to_teacher_on_new_user_in_course' => ['default' => 0, 'category' => 'registration'], - 'allow_user_view_user_list' => ['default' => 1, 'category' => 'user'], - 'display_info_advance_inside_homecourse' => ['default' => 1, 'category' => 'thematic_advance'], - 'email_alert_students_on_new_homework' => ['default' => 0, 'category' => 'work'], - 'enable_lp_auto_launch' => ['default' => 0, 'category' => 'learning_path'], - 'enable_exercise_auto_launch' => ['default' => 0, 'category' => 'exercise'], - 'enable_document_auto_launch' => ['default' => 0, 'category' => 'document'], - 'pdf_export_watermark_text' => ['default' => '', 'category' => 'learning_path'], - 'allow_public_certificates' => [ - 'default' => api_get_setting('allow_public_certificates') === 'true' ? 1 : '', - 'category' => 'certificates', - ], - 'documents_default_visibility' => ['default' => 'visible', 'category' => 'document'], - 'show_course_in_user_language' => ['default' => 2, 'category' => null], - 'email_to_teachers_on_new_work_feedback' => ['default' => 1, 'category' => null], - ]; - - $counter = 1; - foreach ($settings as $variable => $setting) { - $title = isset($setting['title']) ? $setting['title'] : ''; - Database::query( - "INSERT INTO $TABLESETTING (id, c_id, title, variable, value, category) - VALUES ($counter, $course_id, '".$title."', '".$variable."', '".$setting['default']."', '".$setting['category']."')" - ); - $counter++; - } - - /* Course homepage tools for platform admin only */ - /* Group tool */ Database::insert( $TABLEGROUPCATEGORIES, @@ -1200,240 +854,180 @@ public static function string2binary($variable) */ public static function register_course($params, $accessUrlId = 1) { - global $error_msg, $firstExpirationDelay; - $title = $params['title']; - // Fix amp - $title = str_replace('&', '&', $title); - $code = $params['code']; - $visual_code = $params['visual_code']; - $directory = $params['directory']; - $tutor_name = isset($params['tutor_name']) ? $params['tutor_name'] : null; - $category_code = isset($params['course_category']) ? $params['course_category'] : ''; - $course_language = isset($params['course_language']) && !empty($params['course_language']) ? $params['course_language'] : api_get_setting( - 'platformLanguage' - ); - $user_id = empty($params['user_id']) ? api_get_user_id() : (int) $params['user_id']; - $department_name = isset($params['department_name']) ? $params['department_name'] : null; - $department_url = isset($params['department_url']) ? $params['department_url'] : null; - $disk_quota = isset($params['disk_quota']) ? $params['disk_quota'] : null; - - if (!isset($params['visibility'])) { - $default_course_visibility = api_get_setting( - 'courses_default_creation_visibility' - ); - if (isset($default_course_visibility)) { - $visibility = $default_course_visibility; - } else { - $visibility = COURSE_VISIBILITY_OPEN_PLATFORM; + $title = str_replace('&', '&', $params['title']); + $code = array_key_exists('code', $params) ? $params['code'] : null; + $visualCode = array_key_exists('visual_code', $params) ? $params['visual_code'] : null; + $directory = array_key_exists('directory', $params) ? $params['directory'] : null; + $tutorName = array_key_exists('tutor_name', $params) ? $params['tutor_name'] : null; + $categoryCode = array_key_exists('course_category', $params) ? $params['course_category'] : ''; + $courseLanguage = array_key_exists('course_language', $params) && !empty($params['course_language']) + ? $params['course_language'] + : api_get_setting('platformLanguage'); + $userId = empty($params['user_id']) ? api_get_user_id() : (int) $params['user_id']; + $departmentName = array_key_exists('department_name', $params) ? $params['department_name'] : null; + $departmentUrl = array_key_exists('department_url', $params) ? $params['department_url'] : null; + $diskQuota = array_key_exists('disk_quota', $params) ? $params['disk_quota'] : null; + $visibility = array_key_exists('visibility', $params) ? $params['visibility'] : null; + $subscribe = array_key_exists('subscribe', $params) ? $params['subscribe'] : null; + $unsubscribe = array_key_exists('unsubscribe', $params) ? $params['unsubscribe'] : null; + $teachers = array_key_exists('teachers', $params) ? $params['teachers'] : null; + + $expirationDate = null; + if (array_key_exists('expiration_date', $params)) { + $date = $params['expiration_date']; + try { + $expirationDate = new DateTime(api_get_utc_datetime($date), new DateTimeZone('utc')); + } catch (Exception $exception) { + error_log(sprintf('expiration_date "%s" is invalid', $date)); + + return 0; } - } else { - $visibility = $params['visibility']; } - if (isset($params['subscribe'])) { - $subscribe = (int) $params['subscribe']; - } else { - $subscribe = $visibility == COURSE_VISIBILITY_OPEN_PLATFORM ? 1 : 0; - } - $unsubscribe = isset($params['unsubscribe']) ? (int) $params['unsubscribe'] : 0; - $expiration_date = isset($params['expiration_date']) ? $params['expiration_date'] : null; - $teachers = isset($params['teachers']) ? $params['teachers'] : null; - $status = isset($params['status']) ? $params['status'] : null; + $user = api_get_user_entity($userId); + if (is_null($user)) { + error_log(sprintf('user_id "%s" is invalid', $userId)); - $TABLECOURSE = Database::get_main_table(TABLE_MAIN_COURSE); - $TABLECOURSUSER = Database::get_main_table(TABLE_MAIN_COURSE_USER); - - $ok_to_register_course = true; - - // Check whether all the needed parameters are present. - if (empty($code)) { - $error_msg[] = 'courseSysCode is missing'; - $ok_to_register_course = false; - } - if (empty($visual_code)) { - $error_msg[] = 'courseScreenCode is missing'; - $ok_to_register_course = false; - } - if (empty($directory)) { - $error_msg[] = 'courseRepository is missing'; - $ok_to_register_course = false; + return 0; } - if (empty($title)) { - $error_msg[] = 'title is missing'; - $ok_to_register_course = false; + $course = (new \Chamilo\CoreBundle\Entity\Course()) + ->setCode($code) + ->setDirectory($directory) + ->setCourseLanguage($courseLanguage) + ->setTitle($title) + ->setCategoryCode($categoryCode) + ->setVisibility($visibility) + ->setDiskQuota($diskQuota) + ->setExpirationDate($expirationDate) + ->setTutorName($tutorName) + ->setDepartmentName($departmentName) + ->setDepartmentUrl($departmentUrl) + ->setSubscribe($subscribe) + ->setUnsubscribe($unsubscribe) + ->setVisualCode($visualCode) + ; + + $url = api_get_access_url_entity($accessUrlId); + if (!is_null($url)) { + $course->getAccessUrls()->add($url); } - if (empty($expiration_date)) { - $expiration_date = api_get_utc_datetime( - time() + $firstExpirationDelay - ); - } else { - $expiration_date = api_get_utc_datetime($expiration_date); + Database::getManager()->persist($course); + + $addTeacher = isset($params['add_user_as_teacher']) ? $params['add_user_as_teacher'] : true; + if ($addTeacher) { + $iCourseSort = CourseManager::userCourseSort($userId, $code); + $courseRelTutor = (new CourseRelUser()) + ->setCourse($course) + ->setUser($user) + ->setStatus(true) + ->setTutor(true) + ->setSort($iCourseSort) + ->setRelationType(0) + ->setUserCourseCat(0) + ; + Database::getManager()->persist($courseRelTutor); } - if ($visibility < 0 || $visibility > 4) { - $error_msg[] = 'visibility is invalid'; - $ok_to_register_course = false; - } - - if (empty($disk_quota)) { - $disk_quota = api_get_setting('default_document_quotum'); + if (!empty($teachers)) { + $sort = $user->getMaxSortValue(); + if (!is_array($teachers)) { + $teachers = [$teachers]; + } + foreach ($teachers as $key) { + // Just in case. + if ($key == $userId) { + continue; + } + if (empty($key)) { + continue; + } + $teacher = api_get_user_entity($key); + if (is_null($teacher)) { + continue; + } + $courseRelTeacher = (new CourseRelUser()) + ->setCourse($course) + ->setUser($teacher) + ->setStatus(true) + ->setTutor(false) + ->setSort($sort + 1) + ->setRelationType(0) + ->setUserCourseCat(0) + ; + Database::getManager()->persist($courseRelTeacher); + } } - $time = api_get_utc_datetime(); + try { + Database::getManager()->flush(); + } catch (OptimisticLockException $exception) { + error_log($exception); - if (stripos($department_url, 'http://') === false && stripos( - $department_url, - 'https://' - ) === false - ) { - $department_url = 'http://'.$department_url; + return 0; } - // Just in case - if ($department_url === 'http://') { - $department_url = ''; - } - $course_id = 0; - if ($ok_to_register_course) { - // Here we must add 2 fields. - $course_id = Database::insert( - $TABLECOURSE, - [ - 'code' => $code, - 'directory' => $directory, - 'course_language' => $course_language, - 'title' => $title, - 'description' => get_lang('CourseDescription'), - 'category_code' => $category_code, - 'visibility' => $visibility, - 'show_score' => 1, - 'disk_quota' => (int) $disk_quota, - 'creation_date' => $time, - 'expiration_date' => $expiration_date, - 'last_edit' => $time, - 'last_visit' => null, - 'tutor_name' => $tutor_name, - 'department_name' => $department_name, - 'department_url' => $department_url, - 'subscribe' => $subscribe, - 'unsubscribe' => $unsubscribe, - 'visual_code' => $visual_code, - ] - ); - - if ($course_id) { - $sort = api_max_sort_value('0', api_get_user_id()); - // Default true - $addTeacher = isset($params['add_user_as_teacher']) ? $params['add_user_as_teacher'] : true; - if ($addTeacher) { - $i_course_sort = CourseManager:: userCourseSort( - $user_id, - $code - ); - if (!empty($user_id)) { - $sql = "INSERT INTO $TABLECOURSUSER SET - c_id = $course_id, - user_id = '".intval($user_id)."', - status = '1', - is_tutor = '0', - sort = '".($i_course_sort)."', - relation_type = 0, - user_course_cat = '0'"; - Database::query($sql); - } - } - - if (!empty($teachers)) { - if (!is_array($teachers)) { - $teachers = [$teachers]; - } - foreach ($teachers as $key) { - // Just in case. - if ($key == $user_id) { - continue; - } - if (empty($key)) { - continue; - } - $sql = "INSERT INTO ".$TABLECOURSUSER." SET - c_id = '".Database::escape_string($course_id)."', - user_id = '".Database::escape_string($key)."', - status = '1', - is_tutor = '0', - sort = '".($sort + 1)."', - relation_type = 0, - user_course_cat = '0'"; - Database::query($sql); - } - } + $courseId = $course->getId(); + + // Add event to the system log. + $userId = api_get_user_id(); + Event::addEvent( + LOG_COURSE_CREATE, + LOG_COURSE_CODE, + $code, + api_get_utc_datetime(), + $userId, + $courseId + ); - // Adding the course to an URL. - UrlManager::add_course_to_url($course_id, $accessUrlId); - - // Add event to the system log. - $user_id = api_get_user_id(); - Event::addEvent( - LOG_COURSE_CREATE, - LOG_COURSE_CODE, - $code, - api_get_utc_datetime(), - $user_id, - $course_id - ); + $send_mail_to_admin = api_get_setting('send_email_to_admin_when_create_course'); - $send_mail_to_admin = api_get_setting('send_email_to_admin_when_create_course'); + // @todo Improve code to send to all current portal administrators. + if ($send_mail_to_admin === 'true') { + $siteName = api_get_setting('siteName'); + $recipient_email = api_get_setting('emailAdministrator'); + $recipient_name = api_get_person_name( + api_get_setting('administratorName'), + api_get_setting('administratorSurname') + ); + $iname = api_get_setting('Institution'); + $subject = get_lang('NewCourseCreatedIn').' '.$siteName.' - '.$iname; + $message = get_lang( + 'Dear' + ).' '.$recipient_name.",\n\n".get_lang( + 'MessageOfNewCourseToAdmin' + ).' '.$siteName.' - '.$iname."\n"; + $message .= get_lang('CourseName').' '.$title."\n"; + $message .= get_lang( + 'Category' + ).' '.$categoryCode."\n"; + $message .= get_lang('Tutor').' '.$tutorName."\n"; + $message .= get_lang('Language').' '.$courseLanguage; + + $userInfo = api_get_user_info($userId); + $additionalParameters = [ + 'smsType' => SmsPlugin::NEW_COURSE_BEEN_CREATED, + 'userId' => $userId, + 'courseName' => $title, + 'creatorUsername' => $userInfo['username'], + ]; - // @todo Improve code to send to all current portal administrators. - if ($send_mail_to_admin === 'true') { - $siteName = api_get_setting('siteName'); - $recipient_email = api_get_setting('emailAdministrator'); - $recipient_name = api_get_person_name( - api_get_setting('administratorName'), - api_get_setting('administratorSurname') - ); - $iname = api_get_setting('Institution'); - $subject = get_lang( - 'NewCourseCreatedIn' - ).' '.$siteName.' - '.$iname; - $message = get_lang( - 'Dear' - ).' '.$recipient_name.",\n\n".get_lang( - 'MessageOfNewCourseToAdmin' - ).' '.$siteName.' - '.$iname."\n"; - $message .= get_lang('CourseName').' '.$title."\n"; - $message .= get_lang( - 'Category' - ).' '.$category_code."\n"; - $message .= get_lang('Tutor').' '.$tutor_name."\n"; - $message .= get_lang('Language').' '.$course_language; - - $userInfo = api_get_user_info($user_id); - $additionalParameters = [ - 'smsType' => SmsPlugin::NEW_COURSE_BEEN_CREATED, - 'userId' => $user_id, - 'courseName' => $title, - 'creatorUsername' => $userInfo['username'], - ]; - - api_mail_html( - $recipient_name, - $recipient_email, - $subject, - $message, - $siteName, - $recipient_email, - null, - null, - null, - $additionalParameters - ); - } - } + api_mail_html( + $recipient_name, + $recipient_email, + $subject, + $message, + $siteName, + $recipient_email, + null, + null, + null, + $additionalParameters + ); } - return $course_id; + return $courseId; } /** diff --git a/main/inc/lib/api.lib.php b/main/inc/lib/api.lib.php index f9eef2c0868..95b06f007be 100644 --- a/main/inc/lib/api.lib.php +++ b/main/inc/lib/api.lib.php @@ -1,10 +1,15 @@ getRepository('ChamiloCoreBundle:Session')->find($id); } +/** + * @param int $id the learning path identifier + * + * @return CLp|null + */ +function api_get_lp_entity($id) +{ + return Database::getManager()->getRepository('ChamiloCourseBundle:CLp')->find($id); +} + /** * Returns the current course info array. @@ -2611,6 +2626,16 @@ function api_get_group_id() return Session::read('_gid', 0); } +/** + * @param int $id the group identifier + * + * @return CGroupInfo|object|null + */ +function api_get_group_entity($id = 0) +{ + return Database::getManager()->getRepository('ChamiloCourseBundle:CGroupInfo')->find($id ?: api_get_group_id()); +} + /** * Gets the current or given session name. * @@ -4193,289 +4218,66 @@ function api_item_property_update( $end_visible = '', $session_id = 0 ) { - if (empty($_course)) { + if (!array_key_exists('real_id', $_course)) { return false; } - - $course_id = $_course['real_id']; - - if (empty($course_id)) { + $course = api_get_course_entity($_course['real_id']); + if (is_null($course)) { return false; } - $to_group_id = 0; - if (!empty($groupInfo) && isset($groupInfo['iid'])) { - $to_group_id = (int) $groupInfo['iid']; - } - - $em = Database::getManager(); - - // Definition of variables. - $tool = Database::escape_string($tool); - $item_id = (int) $item_id; - $lastEditTypeNoFilter = $last_edit_type; - $last_edit_type = Database::escape_string($last_edit_type); - $user_id = (int) $user_id; - - $startVisible = "NULL"; - if (!empty($start_visible)) { - $start_visible = Database::escape_string($start_visible); - $startVisible = "'$start_visible'"; - } - - $endVisible = "NULL"; - if (!empty($end_visible)) { - $end_visible = Database::escape_string($end_visible); - $endVisible = "'$end_visible'"; - } - - $to_filter = ''; - $time = api_get_utc_datetime(); - - if (!empty($session_id)) { - $session_id = (int) $session_id; - } else { - $session_id = api_get_session_id(); - } - - // Definition of tables. - $tableItemProperty = Database::get_course_table(TABLE_ITEM_PROPERTY); - - if ($to_user_id <= 0) { - $to_user_id = null; // No to_user_id set - } - - if (!is_null($to_user_id)) { - // $to_user_id has more priority than $to_group_id - $to_user_id = (int) $to_user_id; - $to_field = 'to_user_id'; - $to_value = $to_user_id; - } else { - // $to_user_id is not set. - $to_field = 'to_group_id'; - $to_value = $to_group_id; - } - - $toValueCondition = empty($to_value) ? 'NULL' : "'$to_value'"; - // Set filters for $to_user_id and $to_group_id, with priority for $to_user_id - $condition_session = " AND session_id = $session_id "; - if (empty($session_id)) { - $condition_session = ' AND (session_id = 0 OR session_id IS NULL) '; - } - - $filter = " c_id = $course_id AND tool = '$tool' AND ref = $item_id $condition_session "; - - // Check whether $to_user_id and $to_group_id are passed in the function call. - // If both are not passed (both are null) then it is a message for everybody and $to_group_id should be 0 ! - if (is_null($to_user_id) && is_null($to_group_id)) { - $to_group_id = 0; - } - - if (!is_null($to_user_id)) { - // Set filter to intended user. - $to_filter = " AND to_user_id = $to_user_id $condition_session"; - } else { - // Set filter to intended group. - if (($to_group_id != 0) && $to_group_id == strval(intval($to_group_id))) { - $to_filter = " AND to_group_id = $to_group_id $condition_session"; - } - } - - // Adding filter if set. - $filter .= $to_filter; + $toUser = api_get_user_entity($to_user_id); + $toGroup = array_key_exists('iid', $groupInfo) ? api_get_group_entity($groupInfo['iid']) : null; + $user = api_get_user_entity($user_id) ?: api_get_user_entity(api_get_anonymous_id()); + $session = api_get_session_entity($session_id); - // Update if possible - $set_type = ''; + $startVisibleDate = empty($start_visible) + ? null + : new DateTime($start_visible, new DateTimeZone('UTC')); + $endVisibleDate = empty($end_visible) + ? null + : new DateTime($end_visible, new DateTimeZone('UTC')); - switch ($lastEditTypeNoFilter) { - case 'delete': - // delete = make item only visible for the platform admin. - $visibility = '2'; - if (!empty($session_id)) { - // Check whether session id already exist into item_properties for updating visibility or add it. - $sql = "SELECT session_id FROM $tableItemProperty - WHERE - c_id = $course_id AND - tool = '$tool' AND - ref = $item_id AND - session_id = $session_id"; - $rs = Database::query($sql); - if (Database::num_rows($rs) > 0) { - $sql = "UPDATE $tableItemProperty - SET lastedit_type = '".str_replace('_', '', ucwords($tool))."Deleted', - lastedit_date = '$time', - lastedit_user_id = $user_id, - visibility = $visibility, - session_id = $session_id $set_type - WHERE $filter"; - $result = Database::query($sql); - } else { - $sql = "INSERT INTO $tableItemProperty (c_id, tool, ref, insert_date, insert_user_id, lastedit_date, lastedit_type, lastedit_user_id, $to_field, visibility, start_visible, end_visible, session_id) - VALUES ($course_id, '$tool',$item_id, '$time', $user_id, '$time', '$last_edit_type',$user_id, $toValueCondition, $visibility, $startVisible, $endVisible, $session_id)"; - $result = Database::query($sql); - $id = Database::insert_id(); - if ($id) { - $sql = "UPDATE $tableItemProperty SET id = iid WHERE iid = $id"; - Database::query($sql); - } - } - } else { - $sql = "UPDATE $tableItemProperty - SET - lastedit_type='".str_replace('_', '', ucwords($tool))."Deleted', - lastedit_date='$time', - lastedit_user_id = $user_id, - visibility = $visibility $set_type - WHERE $filter"; - $result = Database::query($sql); - } - break; - case 'visible': // Change item to visible. - $visibility = '1'; - if (!empty($session_id)) { - // Check whether session id already exist into item_properties for updating visibility or add it. - $sql = "SELECT session_id FROM $tableItemProperty - WHERE - c_id = $course_id AND - tool = '$tool' AND - ref = $item_id AND - session_id = $session_id"; - $rs = Database::query($sql); - if (Database::num_rows($rs) > 0) { - $sql = "UPDATE $tableItemProperty - SET - lastedit_type='".str_replace('_', '', ucwords($tool))."Visible', - lastedit_date='$time', - lastedit_user_id = $user_id, - visibility = $visibility, - session_id = $session_id $set_type - WHERE $filter"; - $result = Database::query($sql); - } else { - $sql = "INSERT INTO $tableItemProperty (c_id, tool, ref, insert_date, insert_user_id, lastedit_date, lastedit_type, lastedit_user_id, $to_field, visibility, start_visible, end_visible, session_id) - VALUES ($course_id, '$tool', $item_id, '$time', $user_id, '$time', '$last_edit_type', $user_id, $toValueCondition, $visibility, $startVisible, $endVisible, $session_id)"; - $result = Database::query($sql); - $id = Database::insert_id(); - if ($id) { - $sql = "UPDATE $tableItemProperty SET id = iid WHERE iid = $id"; - Database::query($sql); - } - } - } else { - $sql = "UPDATE $tableItemProperty - SET - lastedit_type='".str_replace('_', '', ucwords($tool))."Visible', - lastedit_date='$time', - lastedit_user_id = $user_id, - visibility = $visibility $set_type - WHERE $filter"; - $result = Database::query($sql); - } - break; - case 'invisible': // Change item to invisible. - $visibility = '0'; - if (!empty($session_id)) { - // Check whether session id already exist into item_properties for updating visibility or add it - $sql = "SELECT session_id FROM $tableItemProperty - WHERE - c_id = $course_id AND - tool = '$tool' AND - ref = $item_id AND - session_id = $session_id"; - $rs = Database::query($sql); - if (Database::num_rows($rs) > 0) { - $sql = "UPDATE $tableItemProperty - SET - lastedit_type = '".str_replace('_', '', ucwords($tool))."Invisible', - lastedit_date = '$time', - lastedit_user_id = $user_id, - visibility = $visibility, - session_id = $session_id $set_type - WHERE $filter"; - $result = Database::query($sql); - } else { - $sql = "INSERT INTO $tableItemProperty (c_id, tool, ref, insert_date, insert_user_id, lastedit_date, lastedit_type, lastedit_user_id,$to_field, visibility, start_visible, end_visible, session_id) - VALUES ($course_id, '$tool', $item_id, '$time', $user_id, '$time', '$last_edit_type', $user_id, $toValueCondition, $visibility, $startVisible, $endVisible, $session_id)"; - $result = Database::query($sql); - $id = Database::insert_id(); - if ($id) { - $sql = "UPDATE $tableItemProperty SET id = iid WHERE iid = $id"; - Database::query($sql); - } - } - } else { - $sql = "UPDATE $tableItemProperty - SET - lastedit_type = '".str_replace('_', '', ucwords($tool))."Invisible', - lastedit_date = '$time', - lastedit_user_id = $user_id, - visibility = $visibility $set_type - WHERE $filter"; - $result = Database::query($sql); - } - break; - default: // The item will be added or updated. - $set_type = ", lastedit_type = '$last_edit_type' "; - $visibility = '1'; - //$filter .= $to_filter; already added - $sql = "UPDATE $tableItemProperty - SET - lastedit_date = '$time', - lastedit_user_id = $user_id $set_type - WHERE $filter"; - $result = Database::query($sql); - } - - // Insert if no entries are found (can only happen in case of $last_edit_type switch is 'default'). - if ($result == false || Database::affected_rows($result) == 0) { - $objCourse = $em->find('ChamiloCoreBundle:Course', intval($course_id)); - $objTime = new DateTime('now', new DateTimeZone('UTC')); - $objUser = api_get_user_entity($user_id); - if (empty($objUser)) { - // Use anonymous - $user_id = api_get_anonymous_id(); - $objUser = api_get_user_entity($user_id); - } - - $objGroup = null; - if (!empty($to_group_id)) { - $objGroup = $em->find('ChamiloCourseBundle:CGroupInfo', $to_group_id); - } - - $objToUser = api_get_user_entity($to_user_id); - $objSession = $em->find('ChamiloCoreBundle:Session', intval($session_id)); - - $startVisibleDate = !empty($start_visible) ? new DateTime($start_visible, new DateTimeZone('UTC')) : null; - $endVisibleDate = !empty($endVisibleDate) ? new DateTime($endVisibleDate, new DateTimeZone('UTC')) : null; - - $cItemProperty = new CItemProperty($objCourse); - $cItemProperty - ->setTool($tool) - ->setRef($item_id) - ->setInsertDate($objTime) - ->setInsertUser($objUser) - ->setLasteditDate($objTime) - ->setLasteditType($last_edit_type) - ->setGroup($objGroup) - ->setToUser($objToUser) - ->setVisibility($visibility) - ->setStartVisible($startVisibleDate) - ->setEndVisible($endVisibleDate) - ->setSession($objSession); - - $em->persist($cItemProperty); - $em->flush(); - - $id = $cItemProperty->getIid(); - - if ($id) { - $cItemProperty->setId($id); - $em->merge($cItemProperty); - $em->flush(); - - return false; - } - } + $visibilityReference = [ + 'delete' => 2, // only site admin + 'visible' => 1, + 'invisible' => 0, + ]; + $visibility = array_key_exists($last_edit_type, $visibilityReference) + ? $visibilityReference[$last_edit_type] + : 1; + $lastEditTypeFinal = array_key_exists($last_edit_type, $visibilityReference) + ? sprintf('%s%s', str_replace('_', '', ucwords($tool)), ucfirst($last_edit_type)) + : $last_edit_type; + + /** @var CItemProperty|null $itemProperty */ + $itemProperty = ( + $course->getItemProperties()->matching( + Criteria::create() + ->where(Criteria::expr()->eq('tool', $tool)) + ->andWhere(Criteria::expr()->eq('ref', $item_id)) + ->andWhere(Criteria::expr()->eq('session', $session)) + ->andWhere( + is_null($toUser) + ? Criteria::expr()->eq('group', $toGroup) + : Criteria::expr()->eq('toUser', $toUser) + ) + )->first() ?: ( + (new CItemProperty($course)) + ->setTool($tool) + ->setRef($item_id) + ->setToUser($toUser) + ->setGroup($toGroup) + ->setSession($session) + ) + ) + ->setLasteditType($lastEditTypeFinal) + ->setLasteditUserId($user->getId()) + ->setVisibility($visibility) + ->setStartVisible($startVisibleDate) + ->setEndVisible($endVisibleDate); + Database::getManager()->persist($itemProperty); + Database::getManager()->flush($itemProperty); return true; } @@ -5260,20 +5062,11 @@ function api_get_themes($getOnlyThemeFromVirtualInstance = false) */ function api_max_sort_value($user_course_category, $user_id) { - $tbl_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER); - $sql = "SELECT max(sort) as max_sort FROM $tbl_course_user - WHERE - user_id='".intval($user_id)."' AND - relation_type<>".COURSE_RELATION_TYPE_RRHH." AND - user_course_cat='".intval($user_course_category)."'"; - $result_max = Database::query($sql); - if (Database::num_rows($result_max) == 1) { - $row_max = Database::fetch_array($result_max); - - return $row_max['max_sort']; - } + /** @var User $user */ + $user = User::getRepository()->find($user_id); + $userCourseCategory = UserCourseCategory::getRepository()->find($user_course_category); - return 0; + return is_null($user) ? 0 : $user->getMaxSortValue($userCourseCategory); } /** @@ -6616,6 +6409,18 @@ function api_get_access_url_from_user($user_id) return $list; } +/** + * @param int $id the access url identifier + * + * @return AccessUrl|null + */ +function api_get_access_url_entity($id = 0) +{ + return Database::getManager()->getRepository('ChamiloCoreBundle:AccessUrl')->find( + $id ?: api_get_current_access_url_id() + ); +} + /** * Gets the status of a user in a course. * diff --git a/main/inc/lib/course.lib.php b/main/inc/lib/course.lib.php index a89b6eff893..965e1a1cc0f 100755 --- a/main/inc/lib/course.lib.php +++ b/main/inc/lib/course.lib.php @@ -48,11 +48,6 @@ public static function create_course($params, $authorId = 0, $accessUrlId = 0) $hook = HookCreateCourse::create(); - // Check portal limits - $accessUrlId = empty($accessUrlId) - ? (api_get_multiple_access_url() ? api_get_current_access_url_id() : 1) - : $accessUrlId; - $authorId = empty($authorId) ? api_get_user_id() : (int) $authorId; if (isset($_configuration[$accessUrlId]) && is_array($_configuration[$accessUrlId])) { @@ -76,45 +71,18 @@ public static function create_course($params, $authorId = 0, $accessUrlId = 0) } } - if (empty($params['title'])) { - return false; - } - - if (empty($params['wanted_code'])) { - $params['wanted_code'] = $params['title']; - // Check whether the requested course code has already been occupied. - $substring = api_substr($params['title'], 0, self::MAX_COURSE_LENGTH_CODE); - if ($substring === false || empty($substring)) { - return false; - } else { - $params['wanted_code'] = self::generate_course_code($substring); - } - } - - // Create the course keys - $keys = AddCourse::define_course_keys($params['wanted_code']); $params['exemplary_content'] = isset($params['exemplary_content']) ? $params['exemplary_content'] : false; - if (count($keys)) { - $params['code'] = $keys['currentCourseCode']; - $params['visual_code'] = $keys['currentCourseId']; - $params['directory'] = $keys['currentCourseRepository']; - $course_info = api_get_course_info($params['code']); - if (empty($course_info)) { - $course_id = AddCourse::register_course($params, $accessUrlId); - $course_info = api_get_course_info_by_id($course_id); - - if ($hook) { - $hook->setEventData(['course_info' => $course_info]); - $hook->notifyCreateCourse(HOOK_EVENT_TYPE_POST); - } - - if (!empty($course_info)) { - self::fillCourse($course_info, $params, $authorId); - - return $course_info; - } + $courseId = AddCourse::register_course($params, $accessUrlId); + if ($courseId) { + $courseInfo = api_get_course_info_by_id($courseId); + if ($hook) { + $hook->setEventData(['course_info' => $courseInfo]); + $hook->notifyCreateCourse(HOOK_EVENT_TYPE_POST); } + self::fillCourse($courseInfo, $params, $authorId); + + return $courseInfo; } return false; @@ -597,10 +565,7 @@ public static function autoSubscribeToCourse($courseCode, $status = STUDENT) $userId = api_get_user_id(); if (api_get_configuration_value('catalog_course_subscription_in_user_s_session')) { - /** - * @var Chamilo\UserBundle\Entity\User - */ - $user = UserManager::getRepository()->find($userId); + $user = api_get_user_entity($userId); $sessions = $user->getCurrentlyAccessibleSessions(); if (empty($sessions)) { // user has no accessible session @@ -1228,10 +1193,7 @@ public static function is_user_subscribed_in_course( if (is_null($course)) { return false; } - /** - * @var \Chamilo\UserBundle\Entity\User - */ - $user = UserManager::getRepository()->find($user_id); + $user = api_get_user_entity($user_id); if (is_null($user)) { return false; } @@ -6990,7 +6952,6 @@ private static function fillCourse($courseInfo, $params, $authorId = 0) { $authorId = empty($authorId) ? api_get_user_id() : (int) $authorId; - AddCourse::prepare_course_repository($courseInfo['directory']); AddCourse::fill_db_course( $courseInfo['real_id'], $courseInfo['directory'], diff --git a/main/inc/lib/usermanager.lib.php b/main/inc/lib/usermanager.lib.php index ebc4c52f0c4..b9f3a6ec802 100755 --- a/main/inc/lib/usermanager.lib.php +++ b/main/inc/lib/usermanager.lib.php @@ -146,9 +146,7 @@ public static function encryptPassword($raw, User $user) */ public static function updatePassword($userId, $password) { - $repository = self::getRepository(); - /** @var User $user */ - $user = $repository->find($userId); + $user = api_get_user_entity($userId); $userManager = self::getManager(); $user->setPlainPassword($password); $userManager->updateUser($user, true); @@ -714,7 +712,7 @@ public static function casUserLoginName($casUser) // (extra field values of a deleted user might remain) foreach ($itemList as $item) { $userId = intval($item['item_id']); - $user = UserManager::getRepository()->find($userId); + $user = api_get_user_entity($userId); if (!is_null($user)) { if (false === $loginName) { $loginName = $user->getUsername(); @@ -1366,8 +1364,7 @@ public static function update_user( } $userManager = self::getManager(); - /** @var User $user */ - $user = self::getRepository()->find($user_id); + $user = api_get_user_entity($user_id); if (empty($user)) { return false; diff --git a/main/inc/lib/webservices/Rest.php b/main/inc/lib/webservices/Rest.php index e95b0509310..97cbd04fa29 100644 --- a/main/inc/lib/webservices/Rest.php +++ b/main/inc/lib/webservices/Rest.php @@ -5,7 +5,9 @@ use Chamilo\CoreBundle\Entity\Course; use Chamilo\CoreBundle\Entity\ExtraFieldValues; use Chamilo\CoreBundle\Entity\Session; +use Chamilo\CourseBundle\Entity\CLp; use Chamilo\CourseBundle\Entity\CLpCategory; +use Chamilo\CourseBundle\Entity\CLpItem; use Chamilo\CourseBundle\Entity\CNotebook; use Chamilo\CourseBundle\Entity\Repository\CNotebookRepository; use Chamilo\UserBundle\Entity\User; @@ -68,6 +70,7 @@ class Rest extends WebService const USERNAME_EXIST = 'username_exist'; const GET_COURSE_QUIZ_MDL_COMPAT = 'get_course_quiz_mdl_compat'; const UPDATE_USER_PAUSE_TRAINING = 'update_user_pause_training'; + const CREATE_LEARNINGPATH = 'create_learningpath'; /** * @var Session @@ -1802,8 +1805,7 @@ public function updateUserFromUserName($parameters) if (is_null($userId)) { throw new Exception(get_lang('NoData')); } - /** @var User $user */ - $user = UserManager::getRepository()->find($userId); + $user = api_get_user_entity($userId); if (empty($user)) { throw new Exception(get_lang('CouldNotLoadUser')); } @@ -1914,7 +1916,7 @@ public function updateUserFromUserName($parameters) $fieldValue = $field['field_value']; if (!isset($fieldName) || !isset($fieldValue) || !UserManager::update_extra_field_value($userId, $fieldName, $fieldValue)) { - throw new Exception(get_lang('CouldNotUpdateExtraFieldValue').': '.print_r($field, true)); + throw new Exception(sprintf('%s: %s', get_lang('CouldNotUpdateExtraFieldValue'), print_r($field, true))); } } } else { @@ -2039,6 +2041,148 @@ function (array $exercise) use ($quizIcon) { return [$json]; } + /** + * Creates a learning path with items. + * + * @param array $spec with these keys : + * session_id + * course_code + * lp_name (learning path name) + * lp_cat_id (learning path category id) + * items, a list of items which are arrays with these keys : + * * display_order_id (position AND local item identifier, used in parent_id and prerequisite_id) + * * parent_id (references display_order_id) + * * type (c_lp_item.item_type : dir, document, quiz…) + * * name_to_find (course resource name) + * * title (learning path item title) + * * prerequisite_id (references display_order_id) + * * prerequisite_min_score + * * prerequisite_max_score + * + * @throws Exception if an item is not found by type and name or a parameter is missing + * + * @return CLp the new learning path + */ + public function createLearningPath(array $spec) + { + foreach (['course_code', 'lp_name'] as $requiredParameter) { + if (!array_key_exists($requiredParameter, $spec)) { + throw new Exception("missing parameter '$requiredParameter': ".print_r($spec, true)); + } + } + $courseCode = $spec['course_code']; + $course = Course::getRepository()->findOneByCode($courseCode); + if (is_null($course)) { + throw new Exception("no course has code '$courseCode'"); + } + $learningPath = (new CLp()) + ->setCourse($course) + ->setName($spec['lp_name']); + if (array_key_exists('session_id', $spec)) { + $sessionId = $spec['session_id']; + if (0 == $sessionId) { + $learningPath->setSessionId(0); + } else { + $session = api_get_session_entity($sessionId); + if (is_null($session)) { + throw new Exception("no session has id '$sessionId'"); + } + /*$learningPath->setSession($session);*/ + $learningPath->setSessionId($sessionId); + } + } + if (array_key_exists('lp_cat_id', $spec)) { + $categoryId = $spec['lp_cat_id']; + if (0 == $categoryId) { + $learningPath->setCategoryId(0); + } else { + $category = CLpCategory::getRepository()->find($categoryId); + if (is_null($category)) { + throw new Exception("no category has id '$categoryId'"); + } + /*$learningPath->setCategory($category);*/ + $learningPath->setCategoryId($categoryId); + } + } + if (array_key_exists('items', $spec)) { + $itemSpecs = $spec['items']; + if (!is_array($itemSpecs)) { + throw new Exception('parameter "items" must be an array'); + } + if (!empty($itemSpecs)) { + $parentDisplayOrders = [0 => 0]; + $prerequisitesDisplayOrders = []; + foreach ($itemSpecs as $itemSpec) { + if (!array_key_exists('display_order_id', $itemSpec)) { + throw new Exception(sprintf('display_order_id missing from item spec: %s', print_r($itemSpec, true))); + } + $displayOrder = $itemSpec['display_order_id']; + $type = (array_key_exists('type', $itemSpec) ? $itemSpec['type'] : 'dir'); + if (!array_key_exists('title', $itemSpec)) { + throw new Exception(sprintf('type missing from item spec: %s', print_r($itemSpec, true))); + } + $title = $itemSpec['title']; + $item = (new CLpItem()) + ->setLearningPath($learningPath) + ->setDisplayOrder($displayOrder) + ->setItemType($type) + ->setTitle($title); + if (in_array($type, ['document', 'final_item', 'forum', 'link', 'quiz'])) { + if (!array_key_exists('name_to_find', $itemSpec)) { + throw new Exception(sprintf('name_to_find missing from %s spec: %s', $type, print_r($itemSpec, true))); + } + $resource = $course->findResource($type, $itemSpec['name_to_find']); + $item->setPath('forum' === $type ? $resource->getForumId() : $resource->getId()); + } + if (array_key_exists($displayOrder, $parentDisplayOrders)) { + throw new Exception(sprintf('this item display order is not unique: %s', $displayOrder)); + } + $parentDisplayOrders[$displayOrder] = array_key_exists('parent_id', $itemSpec) + ? $itemSpec['parent_id'] + : 0; + if (array_key_exists('prerequisite_id', $itemSpec)) { + $prerequisiteId = $itemSpec['prerequisite_id']; + if (!empty($prerequisiteId)) { + $prerequisitesDisplayOrders[$displayOrder] = $prerequisiteId; + if (array_key_exists('prerequisite_min_score', $itemSpec)) { + $prerequisiteMinScore = $itemSpec['prerequisite_min_score']; + if (!empty($prerequisiteMinScore)) { + $item->setPrerequisiteMinScore($prerequisiteMinScore); + } + } + if (array_key_exists('prerequisite_max_score', $itemSpec)) { + $prerequisiteMaxScore = $itemSpec['prerequisite_max_score']; + if (!empty($prerequisiteMaxScore)) { + $item->setPrerequisiteMaxScore($prerequisiteMaxScore); + } + } + } + } + } + Database::getManager()->persist($learningPath); + Database::getManager()->flush(); + // now that items have real identifiers, set their parent, previous, next and prerequisite item ones + $idFromDisplayOrder = [0 => 0]; + /** @var CLpItem $item */ + foreach ($learningPath->getItems() as $item) { + $idFromDisplayOrder[$item->getDisplayOrder()] = $item->getId(); + } + $displayOrderNumbers = array_keys($idFromDisplayOrder); + sort($displayOrderNumbers); + foreach ($learningPath->getItems() as $item) { + $displayOrder = $item->getDisplayOrder(); + $item->setParentItemId($idFromDisplayOrder[$parentDisplayOrders[$displayOrder]]); + if (!empty($prerequisitesDisplayOrders[$displayOrder])) { + $item->setPrerequisite($idFromDisplayOrder[$prerequisitesDisplayOrders[$displayOrder]]); + } + } + } + } + Database::getManager()->flush(); + + return $learningPath; + } + /** * @param array $additionalParams Optional * diff --git a/main/lp/learnpath.class.php b/main/lp/learnpath.class.php index 0348ed919a1..221d24229a0 100755 --- a/main/lp/learnpath.class.php +++ b/main/lp/learnpath.class.php @@ -2,7 +2,6 @@ /* For licensing terms, see /license.txt */ -use Chamilo\CoreBundle\Entity\Repository\CourseRepository; use Chamilo\CoreBundle\Entity\Repository\ItemPropertyRepository; use Chamilo\CourseBundle\Component\CourseCopy\CourseArchiver; use Chamilo\CourseBundle\Component\CourseCopy\CourseBuilder; @@ -508,215 +507,91 @@ public function add_item( $previous = (int) $previous; $id = (int) $id; $max_time_allowed = htmlentities($max_time_allowed); - if (empty($max_time_allowed)) { - $max_time_allowed = 0; - } - $sql = "SELECT COUNT(iid) AS num - FROM $tbl_lp_item - WHERE - c_id = $course_id AND - lp_id = ".$this->get_id()." AND - parent_item_id = $parent "; - - $res_count = Database::query($sql); - $row = Database::fetch_array($res_count); - $num = $row['num']; - - $tmp_previous = 0; - $display_order = 0; - $next = 0; - if ($num > 0) { - if (empty($previous)) { - $sql = "SELECT iid, next_item_id, display_order - FROM $tbl_lp_item - WHERE - c_id = $course_id AND - lp_id = ".$this->get_id()." AND - parent_item_id = $parent AND - previous_item_id = 0 OR - previous_item_id = $parent"; - $result = Database::query($sql); - $row = Database::fetch_array($result); - if ($row) { - $next = $row['iid']; - } - } else { - $previous = (int) $previous; - $sql = "SELECT iid, previous_item_id, next_item_id, display_order - FROM $tbl_lp_item - WHERE - c_id = $course_id AND - lp_id = ".$this->get_id()." AND - id = $previous"; - $result = Database::query($sql); - $row = Database::fetch_array($result); - if ($row) { - $tmp_previous = $row['iid']; - $next = $row['next_item_id']; - $display_order = $row['display_order']; - } - } - } - - $id = (int) $id; - $typeCleaned = Database::escape_string($type); - $max_score = 100; - if ($type === 'quiz' && $id) { - $sql = 'SELECT SUM(ponderation) - FROM '.Database::get_course_table(TABLE_QUIZ_QUESTION).' as quiz_question - INNER JOIN '.Database::get_course_table(TABLE_QUIZ_TEST_QUESTION).' as quiz_rel_question - ON - quiz_question.id = quiz_rel_question.question_id AND - quiz_question.c_id = quiz_rel_question.c_id - WHERE - quiz_rel_question.exercice_id = '.$id." AND - quiz_question.c_id = $course_id AND - quiz_rel_question.c_id = $course_id "; - $rsQuiz = Database::query($sql); - $max_score = Database::result($rsQuiz, 0, 0); - - // Disabling the exercise if we add it inside a LP - $exercise = new Exercise($course_id); - $exercise->read($id); - $exercise->disable(); - $exercise->save(); - } - - $params = [ - 'c_id' => $course_id, - 'lp_id' => $this->get_id(), - 'item_type' => $typeCleaned, - 'ref' => '', - 'title' => $title, - 'description' => $description, - 'path' => $id, - 'max_score' => $max_score, - 'parent_item_id' => $parent, - 'previous_item_id' => $previous, - 'next_item_id' => (int) $next, - 'display_order' => $display_order + 1, - 'prerequisite' => $prerequisites, - 'max_time_allowed' => $max_time_allowed, - 'min_score' => 0, - 'launch_data' => '', - ]; - - if ($prerequisites != 0) { - $params['prerequisite'] = $prerequisites; - } - - $new_item_id = Database::insert($tbl_lp_item, $params); - if ($new_item_id) { - $sql = "UPDATE $tbl_lp_item SET id = iid WHERE iid = $new_item_id"; - Database::query($sql); - - if (!empty($next)) { - $sql = "UPDATE $tbl_lp_item - SET previous_item_id = $new_item_id - WHERE c_id = $course_id AND id = $next AND item_type != '".TOOL_LP_FINAL_ITEM."'"; - Database::query($sql); - } - - // Update the item that should be before the new item. - if (!empty($tmp_previous)) { - $sql = "UPDATE $tbl_lp_item - SET next_item_id = $new_item_id - WHERE c_id = $course_id AND id = $tmp_previous"; - Database::query($sql); - } - - // Update all the items after the new item. - $sql = "UPDATE $tbl_lp_item - SET display_order = display_order + 1 - WHERE - c_id = $course_id AND - lp_id = ".$this->get_id()." AND - iid <> $new_item_id AND - parent_item_id = $parent AND - display_order > $display_order"; - Database::query($sql); - - // Update the item that should come after the new item. - $sql = "UPDATE $tbl_lp_item - SET ref = $new_item_id - WHERE c_id = $course_id AND iid = $new_item_id"; - Database::query($sql); - - $sql = "UPDATE $tbl_lp_item - SET previous_item_id = ".$this->getLastInFirstLevel()." - WHERE c_id = $course_id AND lp_id = {$this->lp_id} AND item_type = '".TOOL_LP_FINAL_ITEM."'"; - Database::query($sql); - - // Upload audio. - if (!empty($_FILES['mp3']['name'])) { - // Create the audio folder if it does not exist yet. - $filepath = api_get_path(SYS_COURSE_PATH).$_course['path'].'/document/'; - if (!is_dir($filepath.'audio')) { - mkdir( - $filepath.'audio', - api_get_permissions_for_new_directories() - ); - $audio_id = add_document( - $_course, - '/audio', - 'folder', - 0, - 'audio', - '', - 0, - true, - null, - $sessionId, - $userId - ); - api_item_property_update( - $_course, - TOOL_DOCUMENT, - $audio_id, - 'FolderCreated', - $userId, - null, - null, - null, - null, - $sessionId - ); - api_item_property_update( - $_course, - TOOL_DOCUMENT, - $audio_id, - 'invisible', - $userId, - null, - null, - null, - null, - $sessionId - ); - } - - $file_path = handle_uploaded_document( + $course = api_get_course_entity($course_id); + $learningPath = api_get_lp_entity($this->get_id()); + $item = (new CLpItem()) + ->setCourse($course) + ->setLearningPath($learningPath) + ->setItemType($type) + ->setTitle($title) + ->setDescription($description) + ->setPath($id) + ->setParentItemId($parent) + ->setPrerequisite($prerequisites) + ->setMaxTimeAllowed($max_time_allowed) + ; + + // Upload audio. + if (!empty($_FILES['mp3']['name'])) { + // Create the audio folder if it does not exist yet. + $filepath = api_get_path(SYS_COURSE_PATH).$_course['path'].'/document/'; + if (!is_dir($filepath.'audio')) { + mkdir( + $filepath.'audio', + api_get_permissions_for_new_directories() + ); + $audio_id = add_document( $_course, - $_FILES['mp3'], - api_get_path(SYS_COURSE_PATH).$_course['path'].'/document', '/audio', - $userId, - '', - '', - '', + 'folder', + 0, + 'audio', '', - false + 0, + true, + null, + $sessionId, + $userId + ); + api_item_property_update( + $_course, + TOOL_DOCUMENT, + $audio_id, + 'FolderCreated', + $userId, + null, + null, + null, + null, + $sessionId + ); + api_item_property_update( + $_course, + TOOL_DOCUMENT, + $audio_id, + 'invisible', + $userId, + null, + null, + null, + null, + $sessionId ); - - // Store the mp3 file in the lp_item table. - $sql = "UPDATE $tbl_lp_item SET - audio = '".Database::escape_string($file_path)."' - WHERE iid = '".intval($new_item_id)."'"; - Database::query($sql); } + + $file_path = handle_uploaded_document( + $_course, + $_FILES['mp3'], + api_get_path(SYS_COURSE_PATH).$_course['path'].'/document', + '/audio', + $userId, + '', + '', + '', + '', + false + ); + + // Store the mp3 file in the lp_item table. + $item->setAudio($file_path); } - return $new_item_id; + \Database::getManager()->persist($item); + \Database::getManager()->flush($item); + + $learningPath->updateFinalItemsPreviousItemId(); + + return $item->getId(); } /** @@ -725,13 +600,13 @@ public function add_item( * @param string $courseCode * @param string $name * @param string $description - * @param string $learnpath - * @param string $origin - * @param string $zipname Zip file containing the learnpath or directory containing the learnpath + * @param string $learnpath (unused) + * @param string $origin (if 'zip', this function does nothing) + * @param string $zipname (unused) * @param string $publicated_on * @param string $expired_on * @param int $categoryId - * @param int $userId + * @param int $userId (unused) * * @return int The new learnpath ID on success, 0 on failure */ @@ -749,138 +624,27 @@ public static function add_lp( ) { global $charset; - if (!empty($courseCode)) { - $courseInfo = api_get_course_info($courseCode); - $course_id = $courseInfo['real_id']; - } else { - $course_id = api_get_course_int_id(); - $courseInfo = api_get_course_info(); - } + if ('zip' !== $origin) { + $course_id = api_get_course_int_id($courseCode); + if ($course_id) { + $course = api_get_course_entity($course_id); + if (!is_null($course)) { + $learningPath = (new CLp()) + ->setCourse($course) + ->setName($name) + ->setDescription(api_htmlentities($description, ENT_QUOTES, $charset)) + ->setPublicatedOn(api_get_utc_datetime($publicated_on, true, true)) + ->setExpiredOn(api_get_utc_datetime($expired_on, true, true)) + ->setCategoryId($categoryId); + Database::getManager()->persist($learningPath); + Database::getManager()->flush(); - $tbl_lp = Database::get_course_table(TABLE_LP_MAIN); - // Check course code exists. - // Check lp_name doesn't exist, otherwise append something. - $i = 0; - $categoryId = (int) $categoryId; - // Session id. - $session_id = api_get_session_id(); - $userId = empty($userId) ? api_get_user_id() : $userId; - - if (empty($publicated_on)) { - $publicated_on = null; - } else { - $publicated_on = Database::escape_string(api_get_utc_datetime($publicated_on)); - } - - if (empty($expired_on)) { - $expired_on = null; - } else { - $expired_on = Database::escape_string(api_get_utc_datetime($expired_on)); - } - - $check_name = "SELECT * FROM $tbl_lp - WHERE c_id = $course_id AND name = '".Database::escape_string($name)."'"; - $res_name = Database::query($check_name); - - while (Database::num_rows($res_name)) { - // There is already one such name, update the current one a bit. - $i++; - $name = $name.' - '.$i; - $check_name = "SELECT * FROM $tbl_lp - WHERE c_id = $course_id AND name = '".Database::escape_string($name)."' "; - $res_name = Database::query($check_name); - } - // New name does not exist yet; keep it. - // Escape description. - // Kevin: added htmlentities(). - $description = Database::escape_string(api_htmlentities($description, ENT_QUOTES, $charset)); - $type = 1; - switch ($learnpath) { - case 'guess': - break; - case 'dokeos': - case 'chamilo': - $type = 1; - break; - case 'aicc': - break; - } - - switch ($origin) { - case 'zip': - // Check zip name string. If empty, we are currently creating a new Chamilo learnpath. - break; - case 'manual': - default: - $get_max = "SELECT MAX(display_order) - FROM $tbl_lp WHERE c_id = $course_id"; - $res_max = Database::query($get_max); - if (Database::num_rows($res_max) < 1) { - $dsp = 1; - } else { - $row = Database::fetch_array($res_max); - $dsp = $row[0] + 1; - } - - $params = [ - 'c_id' => $course_id, - 'lp_type' => $type, - 'name' => $name, - 'description' => $description, - 'path' => '', - 'default_view_mod' => 'embedded', - 'default_encoding' => 'UTF-8', - 'display_order' => $dsp, - 'content_maker' => 'Chamilo', - 'content_local' => 'local', - 'js_lib' => '', - 'session_id' => $session_id, - 'created_on' => api_get_utc_datetime(), - 'modified_on' => api_get_utc_datetime(), - 'publicated_on' => $publicated_on, - 'expired_on' => $expired_on, - 'category_id' => $categoryId, - 'force_commit' => 0, - 'content_license' => '', - 'debug' => 0, - 'theme' => '', - 'preview_image' => '', - 'author' => '', - 'prerequisite' => 0, - 'hide_toc_frame' => 0, - 'seriousgame_mode' => 0, - 'autolaunch' => 0, - 'max_attempts' => 0, - 'subscribe_users' => 0, - 'accumulate_scorm_time' => 1, - ]; - $id = Database::insert($tbl_lp, $params); - - if ($id > 0) { - $sql = "UPDATE $tbl_lp SET id = iid WHERE iid = $id"; - Database::query($sql); - - // Insert into item_property. - api_item_property_update( - $courseInfo, - TOOL_LEARNPATH, - $id, - 'LearnpathAdded', - $userId - ); - api_set_default_visibility( - $id, - TOOL_LEARNPATH, - 0, - $courseInfo, - $session_id, - $userId - ); - - return $id; + return $learningPath->getId(); } - break; + } } + + return 0; } /** @@ -4658,14 +4422,12 @@ public static function categoryIsVisibleForStudent( /** @var ItemPropertyRepository $itemRepo */ $itemRepo = $em->getRepository('ChamiloCourseBundle:CItemProperty'); - /** @var CourseRepository $courseRepo */ - $courseRepo = $em->getRepository('ChamiloCoreBundle:Course'); $session = null; if (!empty($sessionId)) { - $session = $em->getRepository('ChamiloCoreBundle:Session')->find($sessionId); + $session = api_get_session_entity($sessionId); } - $course = $courseRepo->find($courseId); + $course = api_get_course_entity($courseId); if ($courseId != 0) { // Subscribed groups to a LP diff --git a/main/lp/lp_subscribe_users.php b/main/lp/lp_subscribe_users.php index ccd9a31b996..577d59a39ee 100644 --- a/main/lp/lp_subscribe_users.php +++ b/main/lp/lp_subscribe_users.php @@ -57,10 +57,10 @@ /** @var Session $session */ $session = null; if (!empty($sessionId)) { - $session = $em->getRepository('ChamiloCoreBundle:Session')->find($sessionId); + $session = api_get_session_entity($sessionId); } -$course = $courseRepo->find($courseId); +$course = api_get_course_entity($courseId); $subscribedUsers = []; // Getting subscribe users to the course. @@ -159,7 +159,7 @@ } $form->setDefaults($defaults); -$currentUser = api_get_user_entity(api_get_user_id()); +$currentUser = api_get_user_entity(); if ($form->validate()) { $values = $form->getSubmitValues(); diff --git a/main/lp/lp_subscribe_users_to_category.php b/main/lp/lp_subscribe_users_to_category.php index 6932863d2a0..7ed68ce9c1f 100644 --- a/main/lp/lp_subscribe_users_to_category.php +++ b/main/lp/lp_subscribe_users_to_category.php @@ -176,7 +176,7 @@ foreach ($users as $userId) { $categoryUser = new CLpCategoryUser(); - $user = UserManager::getRepository()->find($userId); + $user = api_get_user_entity($userId); if ($user) { $categoryUser->setUser($user); $category->addUser($categoryUser); diff --git a/main/lp/lp_view.php b/main/lp/lp_view.php index 5987a847080..d314beb9887 100755 --- a/main/lp/lp_view.php +++ b/main/lp/lp_view.php @@ -86,7 +86,7 @@ $category = $em->getRepository('ChamiloCourseBundle:CLpCategory')->find($categoryId); $block = false; if ($category) { - $user = UserManager::getRepository()->find($user_id); + $user = api_get_user_entity($user_id); $users = $category->getUsers(); if (!empty($users) && $users->count() > 0) { if ($user && !$category->hasUserAdded($user)) { diff --git a/main/mySpace/lp_tracking.php b/main/mySpace/lp_tracking.php index 25496e3ba67..ba134909e2c 100755 --- a/main/mySpace/lp_tracking.php +++ b/main/mySpace/lp_tracking.php @@ -99,7 +99,7 @@ } $view = $em->getRepository('ChamiloCourseBundle:CLpView')->find($itemView->getLpViewId()); - $lp = $em->getRepository('ChamiloCourseBundle:CLp')->find($view->getLpId()); + $lp = api_get_lp_entity($view->getLpId()); $duration = learnpathItem::getScormTimeFromParameter('js', $itemView->getTotalTime()); $endTime = $itemView->getStartTime() + $itemView->getTotalTime(); diff --git a/main/session/resume_session.php b/main/session/resume_session.php index 913b1a8dddf..e26866ac213 100644 --- a/main/session/resume_session.php +++ b/main/session/resume_session.php @@ -4,7 +4,6 @@ use Chamilo\CoreBundle\Entity\Course; use Chamilo\CoreBundle\Entity\Repository\SequenceResourceRepository; -use Chamilo\CoreBundle\Entity\Repository\SessionRepository; use Chamilo\CoreBundle\Entity\SequenceResource; use Chamilo\CoreBundle\Entity\Session; use Chamilo\CoreBundle\Entity\SessionRelCourseRelUser; @@ -48,10 +47,7 @@ $em = Database::getManager(); $sessionInfo = api_get_session_info($sessionId); -/** @var SessionRepository $sessionRepository */ -$sessionRepository = $em->getRepository('ChamiloCoreBundle:Session'); -/** @var Session $session */ -$session = $sessionRepository->find($sessionId); +$session = api_get_session_entity($sessionId); $sessionCategory = $session->getCategory(); $action = isset($_GET['action']) ? $_GET['action'] : null; @@ -165,6 +161,7 @@ } else { $count = 0; $courseItem = ''; + $sessionRepository = $em->getRepository('ChamiloCoreBundle:Session'); $courses = $sessionRepository->getCoursesOrderedByPosition($session); $allowSkills = api_get_configuration_value('allow_skill_rel_items'); diff --git a/main/webservices/api/tests/CreateLearningPathTest.php b/main/webservices/api/tests/CreateLearningPathTest.php new file mode 100644 index 00000000000..ced01427e28 --- /dev/null +++ b/main/webservices/api/tests/CreateLearningPathTest.php @@ -0,0 +1,347 @@ +findOneByName('Test Session'); + if (is_null(self::$session)) { + self::$session = (new Session()) + ->setName('Test Session'); + Database::getManager()->persist(self::$session); + Database::getManager()->flush(); + } + + self::$course = Course::getRepository()->findOneByCode('TESTCOURSE'); + if (is_null(self::$course)) { + self::$course = (new Course()) + ->setCode('TESTCOURSE') + ->setTitle('Test Course'); + Database::getManager()->persist(self::$course); + Database::getManager()->flush(); + } + + self::$category = CLpCategory::getRepository()->findOneByName('Test Category'); + if (is_null(self::$category)) { + self::$category = (new CLpCategory()) + ->setCourse(self::$course) + ->setName('Test Category'); + Database::getManager()->persist(self::$category); + Database::getManager()->flush(); + } + + self::$document = CDocument::getRepository()->findOneByTitle('Test Document'); + if (is_null(self::$document)) { + self::$document = CDocument::fromFile( + __FILE__, + self::$course, + 'test_document.txt', + 'Test Document' + ); + Database::getManager()->persist(self::$document); + Database::getManager()->flush(); + } + + self::$forum = CForumForum::getRepository()->findOneByForumTitle('Test Forum'); + if (is_null(self::$forum)) { + self::$forum = (new CForumForum()) + ->setCourse(self::$course) + ->setForumTitle('Test Forum'); + Database::getManager()->persist(self::$forum); + Database::getManager()->flush(); + } + + self::$link = Clink::getRepository()->findOneByTitle('Test Link'); + if (is_null(self::$link)) { + self::$link = (new CLink()) + ->setCourse(self::$course) + ->setTitle('Test Link ') + ->setUrl('https://chamilo.org/'); + Database::getManager()->persist(self::$link); + Database::getManager()->flush(); + } + + self::$quiz = CQuiz::getRepository()->findOneByTitle('Test Quiz'); + if (is_null(self::$quiz)) { + self::$quiz = (new CQuiz()) + ->setCourse(self::$course) + ->setTitle('Test Quiz '); + Database::getManager()->persist(self::$quiz); + Database::getManager()->flush(); + } + } + + /** + * creates an empty learning path + * asserts that the learning path was created for the right session and course, with the right name, + * in the right category and that it has no item + */ + public function testCreateEmptyLearningPathWithoutSessionNorCategory() + { + // call the webservice to create the learning path + $name = 'Learning Path '.time(); + $learningPathId = $this->integer( + [ + 'session_id' => 0, + 'course_code' => self::$course->getCode(), + 'lp_name' => $name, + 'lp_cat_id' => 0, + 'items' => [], + ] + ); + + // assert the learning path was created + /** @var CLp $learningPath */ + $learningPath = api_get_lp_entity($learningPathId); + + self::assertNotNull($learningPath); + // in the right course + self::assertEquals(0, $learningPath->getSessionId()); + // with no session nor category + self::assertEquals(self::$course->getId(), $learningPath->getCId()); + self::assertEquals(0, $learningPath->getCategoryId()); + // with the right name + self::assertEquals($name, $learningPath->getName()); + // with no item + self::assertEmpty($learningPath->getItems()); + } + + /** + * creates an empty learning path + * asserts that the learning path was created for the right session and course, with the right name, + * in the right category and that it has no item + */ + public function testCreateEmptyLearningPath() + { + // call the webservice to create the learning path + $name = 'Learning Path '.time(); + $learningPathId = $this->integer( + [ + 'session_id' => self::$session->getId(), + 'course_code' => self::$course->getCode(), + 'lp_name' => $name, + 'lp_cat_id' => self::$category->getId(), + 'items' => [], + ] + ); + + // assert the learning path was created + $learningPath = api_get_lp_entity($learningPathId); + + self::assertNotNull($learningPath); + // in the right session, course and category + self::assertEquals(self::$session->getId(), $learningPath->getSessionId()); + self::assertEquals(self::$course->getId(), $learningPath->getCId()); + self::assertEquals(self::$category->getId(), $learningPath->getCategoryId()); + // with the right name + self::assertEquals($name, $learningPath->getName()); + // with no item + self::assertEmpty($learningPath->getItems()); + } + + /** + * creates a learning path with items + * asserts that the learning path items have the right properties + */ + public function testCreateLearningPathWithItems() + { + $name = 'Learning Path '.time(); + $items = [ + [ + 'display_order_id' => 10, + 'parent_id' => 0, + 'type' => 'document', + 'name_to_find' => self::$document->getTitle(), + 'title' => 'Document title '.time(), + ], + [ + 'display_order_id' => 40, + 'parent_id' => 0, + 'type' => 'forum', + 'name_to_find' => self::$forum->getForumTitle(), + 'title' => 'Forum title '.time(), + 'prerequisite_id' => 20, + 'prerequisite_min_score' => 1, + 'prerequisite_max_score' => 1, + ], + [ + 'display_order_id' => 20, + 'parent_id' => 0, + 'type' => 'link', + 'name_to_find' => self::$link->getTitle(), + 'title' => 'Link title '.time(), + 'prerequisite_id' => 10, + 'prerequisite_min_score' => 1, + 'prerequisite_max_score' => 1, + ], + [ + 'display_order_id' => 30, + 'parent_id' => 0, + 'type' => 'quiz', + 'name_to_find' => self::$quiz->getTitle(), + 'title' => 'Quiz title '.time(), + 'prerequisite_id' => 10, + 'prerequisite_min_score' => 1, + 'prerequisite_max_score' => 1, + ], + [ + 'display_order_id' => 50, + 'parent_id' => 0, + 'type' => TOOL_LP_FINAL_ITEM, + 'name_to_find' => self::$document->getTitle(), + 'title' => 'Final item title '.time(), + 'prerequisite_id' => 40, + 'prerequisite_min_score' => 1, + 'prerequisite_max_score' => 1, + ], + [ + 'display_order_id' => 35, + 'parent_id' => 0, + 'type' => 'dir', + 'title' => 'Chapter 1 title '.time(), + 'prerequisite_id' => 10, + 'prerequisite_min_score' => 1, + 'prerequisite_max_score' => 1, + ], + [ + 'display_order_id' => 1, + 'parent_id' => 35, + 'type' => 'student_publication', + 'title' => 'Student publication title '.time(), + ], + [ + 'display_order_id' => 2, + 'parent_id' => 35, + 'type' => 'student_publication', + 'title' => 'Another student publication title '.time(), + 'prerequisite_id' => 1, + 'prerequisite_min_score' => 1, + 'prerequisite_max_score' => 1, + ], + [ + 'display_order_id' => 3, + 'parent_id' => 35, + 'type' => 'dir', + 'title' => 'Sub-chapter of chapter 1 title '.time(), + ], + [ + 'display_order_id' => 38, + 'parent_id' => 0, + 'type' => 'dir', + 'title' => 'Chapter 2 title '.time(), + ], + ]; + $learningPathId = $this->integer( + [ + 'session_id' => self::$session->getId(), + 'course_code' => self::$course->getCode(), + 'lp_name' => $name, + 'lp_cat_id' => self::$category->getId(), + 'items' => $items, + ] + ); + + // assert the learning path was created as specified + /** @var CLp $learningPath */ + $learningPath = api_get_lp_entity($learningPathId); + + self::assertNotNull($learningPath); + self::assertEquals(self::$session->getId(), $learningPath->getSessionId()); + self::assertEquals(self::$course->getId(), $learningPath->getCId()); + self::assertEquals($name, $learningPath->getName()); + self::assertEquals(self::$category->getId(), $learningPath->getCategoryId()); + self::assertNotEmpty($learningPath->getItems()); + + // assert its item list matches the input specifications + $realIds = [0 => 0]; + foreach ($items as $spec) { + $found = false; + foreach ($learningPath->getItems() as $item) { + if ($spec['type'] === $item->getItemType() && $spec['title'] == $item->getTitle()) { + $found = true; + $displayOrderId = $spec['display_order_id']; + $realIds[$displayOrderId] = $item->getId(); + self::assertEquals($displayOrderId, $item->getDisplayOrder()); + self::assertEquals(self::$course->getId(), $item->getCId()); + if ($item->getItemType() === 'document') { + self::assertEquals(self::$document->getId(), $item->getPath()); + } elseif ($item->getItemType() === 'link') { + self::assertEquals(self::$link->getId(), $item->getPath()); + } + if (array_key_exists('prerequisite_id', $spec) && 0 != $spec['prerequisite_id']) { + self::assertEquals($spec['prerequisite_min_score'], $item->getPrerequisiteMinScore()); + self::assertEquals($spec['prerequisite_max_score'], $item->getPrerequisiteMaxScore()); + } + break; + } + } + self::assertTrue($found, sprintf('item not found: %s', print_r($spec, true))); + } + foreach ($items as $spec) { + foreach ($learningPath->getItems() as $item) { + if ($spec['type'] === $item->getItemType() && $spec['title'] == $item->getTitle()) { + self::assertEquals($realIds[$spec['parent_id']], $item->getParentItemId()); + if (array_key_exists('prerequisite_id', $spec) && 0 != $spec['prerequisite_id']) { + self::assertEquals($realIds[$spec['prerequisite_id']], $item->getPrerequisite()); + } + } + } + } + } +} diff --git a/main/webservices/api/tests/CreateSessionFromModelTest.php b/main/webservices/api/tests/CreateSessionFromModelTest.php index 967d52ff07f..45e46e50816 100644 --- a/main/webservices/api/tests/CreateSessionFromModelTest.php +++ b/main/webservices/api/tests/CreateSessionFromModelTest.php @@ -53,8 +53,7 @@ public function testFromASimpleModel() // assert the session was created and given the returned session id $entityManager = Database::getManager(); - $repository = $entityManager->getRepository('ChamiloCoreBundle:Session'); - $newSession = $repository->find($newSessionId); + $newSession = api_get_session_entity($newSessionId); $this->assertIsObject($newSession); // assert the new session got the right data diff --git a/main/webservices/api/v2.php b/main/webservices/api/v2.php index e08a19efe2c..3661807b584 100644 --- a/main/webservices/api/v2.php +++ b/main/webservices/api/v2.php @@ -217,9 +217,7 @@ $restResponse->setData($data); break; case Rest::SAVE_FORUM_POST: - if ( - empty($_POST['title']) || empty($_POST['text']) || empty($_POST['thread']) || empty($_POST['forum']) - ) { + if (empty($_POST['title']) || empty($_POST['text']) || empty($_POST['thread']) || empty($_POST['forum'])) { throw new Exception(get_lang('NoData')); } @@ -310,7 +308,8 @@ $_POST['sessionName'], $_POST['startDate'], $_POST['endDate'], - isset($_POST['extraFields']) ? $_POST['extraFields'] : []); + isset($_POST['extraFields']) ? $_POST['extraFields'] : [] + ); $restResponse->setData([$newSessionId]); break; case Rest::SUBSCRIBE_USER_TO_SESSION_FROM_USERNAME: @@ -342,10 +341,9 @@ exit; break; case Rest::UPDATE_USER_PAUSE_TRAINING: - $allow = api_get_plugin_setting('pausetraining', 'tool_enable') === 'true'; - $allowPauseFormation = api_get_plugin_setting('pausetraining', 'allow_users_to_edit_pause_formation') === 'true'; - - if (false === $allow || false === $allowPauseFormation) { + if (api_get_plugin_setting('pausetraining', 'tool_enable') !== 'true' + || + api_get_plugin_setting('pausetraining', 'allow_users_to_edit_pause_formation') !== 'true') { throw new Exception(get_lang('Plugin configured')); } @@ -356,6 +354,10 @@ $data = $plugin->updateUserPauseTraining($_POST['user_id'], $_POST); $restResponse->setData([$data]); break; + case Rest::CREATE_LEARNINGPATH: + $learningPath = $restApi->createLearningPath($_POST); + $restResponse->setData([$learningPath->getIid()]); + break; default: throw new Exception(get_lang('InvalidAction')); } diff --git a/main/webservices/registration.soap.php b/main/webservices/registration.soap.php index 0c163d25162..a0ab1f2e7bf 100755 --- a/main/webservices/registration.soap.php +++ b/main/webservices/registration.soap.php @@ -304,8 +304,7 @@ function WSCreateUsers($params) $original_user_id_name ); if ($user_id > 0) { - /** @var User $user */ - $user = $userRepository->find($user_id); + $user = api_get_user_entity($user_id); if ($user && $user->isActive() == false) { if (!is_null($password)) { @@ -532,8 +531,7 @@ function WSCreateUser($params) $userRepository = UserManager::getRepository(); if ($user_id > 0) { - /** @var User $user */ - $user = $userRepository->find($user_id); + $user = api_get_user_entity($user_id); if ($user && $user->isActive() == false) { if (!is_null($password)) { $user->setPlainPassword($password); @@ -867,7 +865,7 @@ function WSCreateUsersPasswordCrypted($params) $count_row = Database::num_rows($res); if ($count_row > 0) { // Check if user is not active. - $sql = "SELECT user_id FROM $table_user + $sql = "SELECT user_id FROM $table_user WHERE user_id ='".$row[1]."' AND active= '0'"; $resu = Database::query($sql); $r_check_user = Database::fetch_row($resu); @@ -1389,7 +1387,7 @@ function WSCreateUserPasswordCrypted($params) phone='".Database::escape_string($phone)."', expiration_date='".Database::escape_string($expiration_date)."', active='1', - hr_dept_id=".intval($hr_dept_id)." + hr_dept_id=".intval($hr_dept_id)." WHERE user_id='".$r_check_user[0]."'"; Database::query($sql); @@ -1459,7 +1457,7 @@ function WSCreateUserPasswordCrypted($params) phone = '".Database::escape_string($phone)."', language = '".Database::escape_string($language)."', registration_date = '".api_get_utc_datetime()."', - roles = 'a:0:{}', + roles = 'a:0:{}', ".$queryExpirationDate." hr_dept_id = '".Database::escape_string($hr_dept_id)."', active = '".Database::escape_string($active)."'"; @@ -1657,8 +1655,7 @@ function WSEditUserCredentials($params) return 0; } - /** @var User $user */ - $user = $userRepository->find($user_id); + $user = api_get_user_entity($user_id); if ($user) { $user->setUsername($username); if (!is_null($password)) { @@ -1787,8 +1784,7 @@ function WSEditUsers($params) } // Edit lastname and firstname only if not empty - /** @var User $user */ - $user = $userRepository->find($user_id); + $user = api_get_user_entity($user_id); if (!empty($lastname)) { $user->setLastname($lastname); @@ -1968,8 +1964,7 @@ function WSEditUser($params) return 0; } - /** @var User $user */ - $user = $userRepository->find($user_id); + $user = api_get_user_entity($user_id); if (!empty($lastname)) { $user->setLastname($lastname); @@ -2139,7 +2134,7 @@ function WSEditUserWithPicture($params) } // Check whether username already exits. - $sql = "SELECT username FROM $table_user + $sql = "SELECT username FROM $table_user WHERE username = '$username' AND id <> $user_id"; $res_un = Database::query($sql); $r_username = Database::fetch_row($res_un); @@ -2148,8 +2143,7 @@ function WSEditUserWithPicture($params) return 0; } - /** @var User $user */ - $user = $userRepository->find($user_id); + $user = api_get_user_entity($user_id); if (!empty($lastname)) { $user->setLastname($lastname); @@ -4768,7 +4762,7 @@ function WSSubscribeUserToCourseSimple($params) error_log('Try to register: user_id= '.$user_id.' to course: '.$course_data['code']); } if (!CourseManager::subscribeUser($user_id, $course_data['code'], $status, 0, false, false)) { - $result = 'User was not registered possible reasons: User already registered to the course, + $result = 'User was not registered possible reasons: User already registered to the course, Course visibility doesnt allow user subscriptions '; if ($debug) { error_log($result); diff --git a/plugin/buycourses/src/service_process.php b/plugin/buycourses/src/service_process.php index e22c8d5de02..27255a5ae1a 100644 --- a/plugin/buycourses/src/service_process.php +++ b/plugin/buycourses/src/service_process.php @@ -104,8 +104,7 @@ } $form->addSelect('info_select', get_lang('User'), $selectOptions); } elseif ($typeCourse) { - /** @var User $user */ - $user = UserManager::getRepository()->find($currentUserId); + $user = api_get_user_entity($currentUserId); $courses = $user->getCourses(); $checker = false; foreach ($courses as $course) { @@ -123,8 +122,7 @@ $form->addSelect('info_select', get_lang('Course'), $selectOptions); } elseif ($typeSession) { $sessions = []; - /** @var User $user */ - $user = UserManager::getRepository()->find($currentUserId); + $user = api_get_user_entity($currentUserId); $userSubscriptions = $user->getSessionCourseSubscriptions(); /** @var SessionRelCourseRelUser $userSubscription */ @@ -146,8 +144,7 @@ } } elseif ($typeFinalLp) { // We need here to check the current user courses first - /** @var User $user */ - $user = UserManager::getRepository()->find($currentUserId); + $user = api_get_user_entity($currentUserId); $courses = $user->getCourses(); $courseLpList = []; $sessionLpList = []; diff --git a/plugin/oauth2/src/OAuth2.php b/plugin/oauth2/src/OAuth2.php index 9439dc86f8d..7ae89cd81f6 100644 --- a/plugin/oauth2/src/OAuth2.php +++ b/plugin/oauth2/src/OAuth2.php @@ -294,10 +294,7 @@ private function getValuesByKey(array $data, $key, $default = []) private function updateUser($userId, $response) { - /** - * @var $user Chamilo\UserBundle\Entity\User - */ - $user = UserManager::getRepository()->find($userId); + $user = api_get_user_entity($userId); $user->setFirstname( $this->getValueByKey($response, $this->get( self::SETTING_RESPONSE_RESOURCE_OWNER_FIRSTNAME diff --git a/src/Chamilo/CoreBundle/Entity/AccessUrl.php b/src/Chamilo/CoreBundle/Entity/AccessUrl.php index c8b4b3115fc..b55636c5888 100644 --- a/src/Chamilo/CoreBundle/Entity/AccessUrl.php +++ b/src/Chamilo/CoreBundle/Entity/AccessUrl.php @@ -3,6 +3,9 @@ namespace Chamilo\CoreBundle\Entity; +use Database; +use DateTime; +use Doctrine\ORM\EntityRepository; use Doctrine\ORM\Mapping as ORM; /** @@ -25,7 +28,7 @@ class AccessUrl /** * @ORM\OneToMany(targetEntity="AccessUrlRelCourse", mappedBy="url", cascade={"persist"}, orphanRemoval=true) */ - protected $course; + protected $courses; /** * @var string @@ -56,7 +59,7 @@ class AccessUrl protected $createdBy; /** - * @var \DateTime + * @var DateTime * * @ORM\Column(name="tms", type="datetime", nullable=true) */ @@ -70,21 +73,31 @@ class AccessUrl protected $urlType; /** - * @ORM\OneToMany(targetEntity="Chamilo\CoreBundle\Entity\SettingsCurrent", mappedBy="url", cascade={"persist"}, orphanRemoval=true) + * @ORM\OneToMany( + * targetEntity="Chamilo\CoreBundle\Entity\SettingsCurrent", + * mappedBy="url", + * cascade={"persist"}, + * orphanRemoval=true + * ) */ //protected $settings; /** - * @ORM\OneToMany(targetEntity="Chamilo\CoreBundle\Entity\SessionCategory", mappedBy="url", cascade={"persist"}, orphanRemoval=true) + * @ORM\OneToMany( + * targetEntity="Chamilo\CoreBundle\Entity\SessionCategory", + * mappedBy="url", + * cascade={"persist"}, + * orphanRemoval=true + * ) */ - protected $sessionCategory; + protected $sessionCategories; /** * AccessUrl constructor. */ public function __construct() { - $this->tms = new \DateTime(); + $this->tms = new DateTime(); $this->createdBy = 1; } @@ -96,6 +109,14 @@ public function __toString() return (string) $this->getUrl(); } + /** + * @return Repository\AccessUrlRepository|EntityRepository + */ + public static function getRepository() + { + return Database::getManager()->getRepository('ChamiloCoreBundle:AccessUrl'); + } + /** * Get id. * @@ -205,7 +226,7 @@ public function getCreatedBy() /** * Set tms. * - * @param \DateTime $tms + * @param DateTime $tms * * @return AccessUrl */ @@ -219,7 +240,7 @@ public function setTms($tms) /** * Get tms. * - * @return \DateTime + * @return DateTime */ public function getTms() { diff --git a/src/Chamilo/CoreBundle/Entity/AccessUrlRelCourse.php b/src/Chamilo/CoreBundle/Entity/AccessUrlRelCourse.php index a3965fb18b8..7ba04f6d535 100644 --- a/src/Chamilo/CoreBundle/Entity/AccessUrlRelCourse.php +++ b/src/Chamilo/CoreBundle/Entity/AccessUrlRelCourse.php @@ -23,13 +23,21 @@ class AccessUrlRelCourse protected $id; /** - * @ORM\ManyToOne(targetEntity="Course", inversedBy="urls", cascade={"persist"}) + * @ORM\ManyToOne( + * targetEntity="Chamilo\CoreBundle\Entity\Course", + * inversedBy="urls", + * cascade={"persist"} + * ) * @ORM\JoinColumn(name="c_id", referencedColumnName="id") */ protected $course; /** - * @ORM\ManyToOne(targetEntity="AccessUrl", inversedBy="course", cascade={"persist"}) + * @ORM\ManyToOne( + * targetEntity="Chamilo\CoreBundle\Entity\AccessUrl", + * inversedBy="courses", + * cascade={"persist"} + * ) * @ORM\JoinColumn(name="access_url_id", referencedColumnName="id") */ protected $url; @@ -75,11 +83,16 @@ public function getUrl() } /** - * @param $course + * @param Course $course + * + * @return AccessUrlRelCourse */ public function setCourse($course) { $this->course = $course; + $this->course->getUrls()->add($this); + + return $this; } /** diff --git a/src/Chamilo/CoreBundle/Entity/Course.php b/src/Chamilo/CoreBundle/Entity/Course.php index bda70884468..6ffbf92cf44 100644 --- a/src/Chamilo/CoreBundle/Entity/Course.php +++ b/src/Chamilo/CoreBundle/Entity/Course.php @@ -3,11 +3,27 @@ namespace Chamilo\CoreBundle\Entity; +use Chamilo\CourseBundle\Entity\CCourseSetting; +use Chamilo\CourseBundle\Entity\CDocument; +use Chamilo\CourseBundle\Entity\CForumForum; +use Chamilo\CourseBundle\Entity\CItemProperty; +use Chamilo\CourseBundle\Entity\CLink; +use Chamilo\CourseBundle\Entity\CLp; +use Chamilo\CourseBundle\Entity\CLpCategory; +use Chamilo\CourseBundle\Entity\CLpItem; +use Chamilo\CourseBundle\Entity\CQuiz; use Chamilo\CourseBundle\Entity\CTool; use Chamilo\UserBundle\Entity\User; +use CourseManager; +use Database; +use DateInterval; +use DateTime; +use DateTimeZone; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Criteria; +use Doctrine\ORM\EntityRepository; use Doctrine\ORM\Mapping as ORM; +use Exception; use Gedmo\Mapping\Annotation as Gedmo; use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; use Symfony\Component\Validator\Constraints as Assert; @@ -27,7 +43,6 @@ * @UniqueEntity("visualCode") * @UniqueEntity("directory") * @ORM\Entity(repositoryClass="Chamilo\CoreBundle\Entity\Repository\CourseRepository") - * @ORM\EntityListeners({"Chamilo\CoreBundle\Entity\Listener\CourseListener"}) */ class Course { @@ -47,16 +62,30 @@ class Course protected $id; /** + * @var CourseRelUser[]|ArrayCollection + * * "orphanRemoval" is needed to delete the CourseRelUser relation * in the CourseAdmin class. The setUsers, getUsers, removeUsers and * addUsers methods need to be added. * - * @ORM\OneToMany(targetEntity="CourseRelUser", mappedBy="course", cascade={"persist"}, orphanRemoval=true) + * @ORM\OneToMany( + * targetEntity="CourseRelUser", + * mappedBy="course", + * cascade={"persist", "remove"}, + * orphanRemoval=true + * ) */ protected $users; /** - * @ORM\OneToMany(targetEntity="AccessUrlRelCourse", mappedBy="course", cascade={"persist"}, orphanRemoval=true) + * @var AccessUrlRelCourse[]|ArrayCollection + * + * @ORM\OneToMany( + * targetEntity="AccessUrlRelCourse", + * mappedBy="course", + * cascade={"persist", "remove"}, + * orphanRemoval=true + * ) */ protected $urls; @@ -71,9 +100,15 @@ class Course protected $sessionUserSubscriptions; /** - * @ORM\OneToMany(targetEntity="Chamilo\CourseBundle\Entity\CItemProperty", mappedBy="course") + * @var ArrayCollection|CItemProperty[] + * + * @ORM\OneToMany( + * targetEntity="Chamilo\CourseBundle\Entity\CItemProperty", + * mappedBy="course", + * cascade={"persist", "remove"} + * ) */ - //protected $items; + protected $itemProperties; /** * @ORM\OneToMany(targetEntity="Chamilo\CourseBundle\Entity\CTool", mappedBy="course", cascade={"persist"}) @@ -188,28 +223,28 @@ class Course protected $diskQuota; /** - * @var \DateTime + * @var DateTime * * @ORM\Column(name="last_visit", type="datetime", nullable=true, unique=false) */ protected $lastVisit; /** - * @var \DateTime + * @var DateTime * * @ORM\Column(name="last_edit", type="datetime", nullable=true, unique=false) */ protected $lastEdit; /** - * @var \DateTime + * @var DateTime * * @ORM\Column(name="creation_date", type="datetime", nullable=true, unique=false) */ protected $creationDate; /** - * @var \DateTime + * @var DateTime * * @ORM\Column(name="expiration_date", type="datetime", nullable=true, unique=false) */ @@ -282,12 +317,128 @@ class Course */ protected $room; + /** + * @ORM\ManyToMany(targetEntity="AccessUrl") + * @ORM\JoinTable(name="access_url_rel_course", + * joinColumns={@ORM\JoinColumn(name="c_id", referencedColumnName="id")}, + * inverseJoinColumns={@ORM\JoinColumn(name="access_url_id", referencedColumnName="id")} + * ) + */ + protected $accessUrls; + + /** + * @var ArrayCollection|CCourseSetting[] + * + * @ORM\OneToMany( + * targetEntity="Chamilo\CourseBundle\Entity\CCourseSetting", + * mappedBy="course", + * cascade={"persist", "remove"} + * ) + */ + protected $settings; + + /** + * @var ArrayCollection|CLpCategory[] + * + * @ORM\OneToMany( + * targetEntity="Chamilo\CourseBundle\Entity\CLpCategory", + * mappedBy="course", + * cascade={"persist", "remove"} + * ) + */ + protected $learningPathCategories; + + /** + * @var ArrayCollection|CLpItem[] + * + * @ORM\OneToMany( + * targetEntity="Chamilo\CourseBundle\Entity\CLpItem", + * mappedBy="course", + * cascade={"persist", "remove"} + * ) + */ + protected $learningPathItems; + + /** + * @var ArrayCollection|CDocument[] + * + * @ORM\OneToMany( + * targetEntity="Chamilo\CourseBundle\Entity\CDocument", + * mappedBy="course", + * cascade={"persist", "remove"} + * ) + */ + protected $documents; + + /** + * @var ArrayCollection|CForumForum[] + * + * @ORM\OneToMany( + * targetEntity="Chamilo\CourseBundle\Entity\CForumForum", + * mappedBy="course", + * cascade={"persist", "remove"} + * ) + */ + protected $forums; + + /** + * @var ArrayCollection|CLink[] + * + * @ORM\OneToMany( + * targetEntity="Chamilo\CourseBundle\Entity\CLink", + * mappedBy="course", + * cascade={"persist", "remove"} + * ) + */ + protected $links; + + /** + * @var ArrayCollection|CQuiz[] + * + * @ORM\OneToMany( + * targetEntity="Chamilo\CourseBundle\Entity\CQuiz", + * mappedBy="course", + * cascade={"persist", "remove"} + * ) + */ + protected $quizzes; + + /** + * @var ArrayCollection|CLp[] + * + * @ORM\OneToMany( + * targetEntity="Chamilo\CourseBundle\Entity\CLp", + * mappedBy="course", + * cascade={"persist", "remove"} + * ) + */ + protected $learningPaths; + /** * Constructor. + * + * @throws Exception */ public function __construct() { - $this->creationDate = new \DateTime(); + $this->activateLegal = 0; + $this->addTeachersToSessionsCourses = false; + $this->creationDate = new DateTime('now', new DateTimeZone('utc')); + $this->lastVisit = null; + $this->showScore = 1; + $this->unsubscribe = false; + $this->accessUrls = new ArrayCollection(); + $this->documents = new ArrayCollection(); + $this->forums = new ArrayCollection(); + $this->itemProperties = new ArrayCollection(); + $this->learningPathCategories = new ArrayCollection(); + $this->learningPathItems = new ArrayCollection(); + $this->learningPaths = new ArrayCollection(); + $this->links = new ArrayCollection(); + $this->quizzes = new ArrayCollection(); + $this->settings = new ArrayCollection(); + $this->tools = new ArrayCollection(); + $this->urls = new ArrayCollection(); $this->users = new ArrayCollection(); } @@ -296,7 +447,129 @@ public function __construct() */ public function __toString() { - return (string) $this->getTitle(); + return sprintf('course %s ("%s")', $this->id, $this->getName()); + } + + /** + * @return Repository\CourseRepository|EntityRepository + */ + public static function getRepository() + { + return Database::getManager()->getRepository('ChamiloCoreBundle:Course'); + } + + /** + * Sets sane values if still unset. + * Makes directory if missing. + * + * @ORM\PrePersist + * + * @throws Exception + */ + public function prePersist() + { + if (empty($this->title)) { + throw new Exception('This course is missing a title'); + } + if (empty($this->code)) { + $this->code = substr( + preg_replace('/[^A-Z0-9]/', '', strtoupper(api_replace_dangerous_char($this->title))), + 0, + CourseManager::MAX_COURSE_LENGTH_CODE + ); + } + $originalCode = $this->code; + $counter = 1; + while (self::getRepository()->matching( + Criteria::create()->where( + Criteria::expr()->eq('code', $this->code) + ) + )->exists(function ($other) { + return $other !== $this; + })) { + $this->code = sprintf('%s_%d', $originalCode, $counter++); + } + if (empty($this->visualCode)) { + $this->visualCode = $this->code; + } + if (empty($this->directory)) { + $this->directory = $this->code; + } + $originalDirectory = $this->directory; + $counter = 1; + while (file_exists($this->getAbsolutePath())) { + $this->directory = sprintf('%s_%d', $originalDirectory, $counter++); + } + if (is_null($this->courseLanguage)) { + $this->courseLanguage = api_get_setting('platformLanguage'); + } + if (is_null($this->description)) { + $this->description = get_lang('CourseDescription'); + } + if (is_null($this->categoryCode)) { + $this->categoryCode = ''; + } + if (is_null($this->visibility)) { + $this->visibility = api_get_setting( + 'courses_default_creation_visibility' + ) ?: COURSE_VISIBILITY_OPEN_PLATFORM; + } elseif ($this->visibility < 0 || $this->visibility > 4) { + throw new Exception('This course visibility in invalid:'.$this->visibility); + } + if (is_null($this->subscribe)) { + $this->subscribe = (COURSE_VISIBILITY_OPEN_PLATFORM == $this->visibility); + } + if (is_null($this->diskQuota)) { + $this->diskQuota = api_get_setting('default_document_quotum'); + } + $this->lastEdit = new DateTime('now', new DateTimeZone('utc')); + if (is_null($this->expirationDate)) { + global $firstExpirationDelay; + $this->expirationDate = new DateTime('now', new DateTimeZone('utc')); + $this->expirationDate->add(new DateInterval(sprintf('PT%dS', $firstExpirationDelay))); + } + if (!empty($this->departmentUrl) && !preg_match("@^https?://@", $this->departmentUrl)) { + $this->departmentUrl = 'https://'.$this->departmentUrl; + } + if ($this->accessUrls->isEmpty()) { + $this->accessUrls->add(api_get_access_url_entity()); + } + $this->prepareRepository(); + $this->createTools(); + $this->createSettings(); + } + + /** + * Removes the course's directory. + * + * @ORM\PostRemove + * + * @throws Exception + */ + public function postRemove() + { + $absolutePath = $this->getAbsolutePath(); + if (!file_exists($absolutePath)) { + if (!rmdir($absolutePath)) { + error_log('Could not remove the course directory '.$absolutePath); + } + } + } + + /** + * Builds the course's directory absolute path. + * + * @throws Exception on undefined directory + * + * @return string the course's directory absolute path + */ + public function getAbsolutePath() + { + if (empty($this->directory)) { + throw new Exception('this course does not have a directory yet'); + } + + return api_get_path(SYS_COURSE_PATH).$this->directory; } /** @@ -348,7 +621,7 @@ public function addTools(CTool $tool) } /** - * @return ArrayCollection + * @return AccessUrlRelCourse[]|ArrayCollection */ public function getUrls() { @@ -360,8 +633,6 @@ public function getUrls() */ public function setUrls($urls) { - $this->urls = new ArrayCollection(); - foreach ($urls as $url) { $this->addUrls($url); } @@ -374,7 +645,7 @@ public function addUrls(AccessUrlRelCourse $url) } /** - * @return ArrayCollection + * @return CourseRelUser[]|ArrayCollection */ public function getUsers() { @@ -425,9 +696,11 @@ public function addUsers(CourseRelUser $courseRelUser) } /** + * @param User $user + * * @return bool */ - public function hasUser(User $user) + public function hasUser($user) { $criteria = Criteria::create()->where( Criteria::expr()->eq("user", $user) @@ -437,9 +710,11 @@ public function hasUser(User $user) } /** + * @param User $user + * * @return bool */ - public function hasStudent(User $user) + public function hasStudent($user) { $criteria = Criteria::create()->where( Criteria::expr()->eq("user", $user) @@ -449,9 +724,11 @@ public function hasStudent(User $user) } /** + * @param User $user + * * @return bool */ - public function hasTeacher(User $user) + public function hasTeacher($user) { $criteria = Criteria::create()->where( Criteria::expr()->eq("user", $user) @@ -462,8 +739,10 @@ public function hasTeacher(User $user) /** * Remove $user. + * + * @param CourseRelUser $user */ - public function removeUsers(CourseRelUser $user) + public function removeUsers($user) { foreach ($this->users as $key => $value) { if ($value->getId() == $user->getId()) { @@ -472,12 +751,18 @@ public function removeUsers(CourseRelUser $user) } } - public function addTeacher(User $user) + /** + * @param User $user + */ + public function addTeacher($user) { $this->addUser($user, 0, "Trainer", User::COURSE_MANAGER); } - public function addStudent(User $user) + /** + * @param User $user + */ + public function addStudent($user) { $this->addUser($user, 0, "", User::STUDENT); } @@ -485,11 +770,15 @@ public function addStudent(User $user) /** * Set id. * - * @return int + * @param int $id + * + * @return Course */ public function setId($id) { $this->id = $id; + + return $this; } /** @@ -832,7 +1121,7 @@ public function getDiskQuota() /** * Set lastVisit. * - * @param \DateTime $lastVisit + * @param DateTime $lastVisit * * @return Course */ @@ -846,7 +1135,7 @@ public function setLastVisit($lastVisit) /** * Get lastVisit. * - * @return \DateTime + * @return DateTime */ public function getLastVisit() { @@ -856,7 +1145,7 @@ public function getLastVisit() /** * Set lastEdit. * - * @param \DateTime $lastEdit + * @param DateTime $lastEdit * * @return Course */ @@ -870,7 +1159,7 @@ public function setLastEdit($lastEdit) /** * Get lastEdit. * - * @return \DateTime + * @return DateTime */ public function getLastEdit() { @@ -880,7 +1169,7 @@ public function getLastEdit() /** * Set creationDate. * - * @param \DateTime $creationDate + * @param DateTime $creationDate * * @return Course */ @@ -894,7 +1183,7 @@ public function setCreationDate($creationDate) /** * Get creationDate. * - * @return \DateTime + * @return DateTime */ public function getCreationDate() { @@ -904,7 +1193,7 @@ public function getCreationDate() /** * Set expirationDate. * - * @param \DateTime $expirationDate + * @param DateTime $expirationDate * * @return Course */ @@ -918,7 +1207,7 @@ public function setExpirationDate($expirationDate) /** * Get expirationDate. * - * @return \DateTime + * @return DateTime */ public function getExpirationDate() { @@ -1136,9 +1425,11 @@ public function getCurrentSession() } /** + * @param Session $session + * * @return $this */ - public function setCurrentSession(Session $session) + public function setCurrentSession($session) { // If the session is registered in the course session list. if ($this->getSessions()->contains($session->getId())) { @@ -1149,9 +1440,126 @@ public function setCurrentSession(Session $session) } /** + * @return CLpCategory[]|ArrayCollection + */ + public function getLearningPathCategories() + { + return $this->learningPathCategories; + } + + /** + * @return CDocument[]|ArrayCollection + */ + public function getDocuments() + { + return $this->documents; + } + + /** + * @return CForumForum[]|ArrayCollection + */ + public function getForums() + { + return $this->forums; + } + + /** + * @return CQuiz[]|ArrayCollection + */ + public function getQuizzes() + { + return $this->quizzes; + } + + /** + * @return CLink[]|ArrayCollection + */ + public function getLinks() + { + return $this->links; + } + + /** + * @return CLp[]|ArrayCollection + */ + public function getLearningPaths() + { + return $this->learningPaths; + } + + /** + * Searches and returns the resource of a specific type having a specific title. + * + * @param string $type 'dir', 'document', 'quiz'… (supported values are hardcoded in this function) + * @param string $title the title of the specific resource to find + * + * @throws Exception when not found or more than one found + * + * @return object the resource + */ + public function findResource($type, $title) + { + $collectionsAndColumns = [ + // type collection column + 'document' => [$this->documents, 'title'], + 'final_item' => [$this->documents, 'title'], + 'forum' => [$this->forums, 'forumTitle'], + 'link' => [$this->links, 'title'], + 'quiz' => [$this->quizzes, 'title'], + ]; + if (!array_key_exists($type, $collectionsAndColumns)) { + throw new Exception(sprintf('unsupported resource type "%s"', $type)); + } + list($collection, $column) = $collectionsAndColumns[$type]; + $resources = $collection->matching(Criteria::create()->where(Criteria::expr()->eq($column, $title))); + if (empty($resources)) { + throw new Exception(sprintf('%s "%s" not found', $type, $title)); + } + if (count($resources) > 1) { + throw new Exception(sprintf('more than one %s "%s" found', $type, $title)); + } + + return $resources[0]; + } + + /** + * @return CLpItem[]|ArrayCollection + */ + public function getLearningPathItems() + { + return $this->learningPathItems; + } + + /** + * @return CItemProperty[]|ArrayCollection + */ + public function getItemProperties() + { + return $this->itemProperties; + } + + /** + * @return CCourseSetting[]|ArrayCollection + */ + public function getSettings() + { + return $this->settings; + } + + /** + * @return AccessUrl[]|ArrayCollection + */ + public function getAccessUrls() + { + return $this->accessUrls; + } + + /** + * @param CourseRelUser $subscription + * * @return bool */ - protected function hasSubscription(CourseRelUser $subscription) + protected function hasSubscription($subscription) { if ($this->getUsers()->count()) { $criteria = Criteria::create()->where( @@ -1171,11 +1579,12 @@ protected function hasSubscription(CourseRelUser $subscription) } /** + * @param User $user * @param string $relationType * @param string $role * @param string $status */ - protected function addUser(User $user, $relationType, $role, $status) + protected function addUser($user, $relationType, $role, $status) { $courseRelUser = new CourseRelUser(); $courseRelUser->setCourse($this); @@ -1185,4 +1594,208 @@ protected function addUser(User $user, $relationType, $role, $status) $courseRelUser->setStatus($status); $this->addUsers($courseRelUser); } + + /** + * Initializes the course's file repository. + * Replaces \AddCourse::prepare_course_repository. + * + * @throws Exception + */ + private function prepareRepository() + { + $dirPermissions = api_get_permissions_for_new_directories(); + $filePermissions = api_get_permissions_for_new_files(); + $indexHtmlContents = ' +Not authorized'; + $repositoryPath = $this->getAbsolutePath(); + if (!file_exists($repositoryPath)) { + if (!mkdir($repositoryPath, $dirPermissions)) { + throw new Exception(sprintf('Could not create course repository "%s"', $repositoryPath)); + } + } + foreach ([ + 'document', + 'dropbox', + 'exercises', + 'group', + 'page', + 'scorm', + 'upload', + 'upload/announcements', + 'upload/announcements/images', + 'upload/blog', + 'upload/calendar', + 'upload/calendar/images', + 'upload/forum', + 'upload/forum/images', + 'upload/learning_path', + 'upload/learning_path/images', + 'upload/test', + 'work', + ] as $relativePath) { + $subfolderPath = $repositoryPath.'/'.$relativePath; + if (!file_exists($subfolderPath)) { + if (!mkdir($subfolderPath, $dirPermissions)) { + throw new Exception(sprintf('Could not create course repository subfolder "%s"', $subfolderPath)); + } + } + $indexHtmlFilePath = $subfolderPath.'/index.html'; + if (!file_exists($indexHtmlFilePath)) { + $indexHtmlFile = fopen($indexHtmlFilePath, 'w'); + if (false === $indexHtmlFile) { + throw new Exception(sprintf('Could not create course repository subfolder index file "%s"', $indexHtmlFilePath)); + } + if (false === fwrite($indexHtmlFile, $indexHtmlContents)) { + throw new Exception(sprintf('Could not write to course repository subfolder index file "%s"', $indexHtmlFilePath)); + } + if (!fclose($indexHtmlFile)) { + throw new Exception(sprintf('Could not close course repository subfolder index file "%s"', $indexHtmlFilePath)); + } + if (!@chmod($indexHtmlFile, $filePermissions)) { + // never mind, on some platforms it is not possible anyway + } + } + } + + // Create .htaccess in the dropbox directory. + $dropboxHtAccessFilePath = $repositoryPath.'/dropbox/.htaccess'; + $dropboxHtAccessFile = fopen($dropboxHtAccessFilePath, 'w'); + if (false === $dropboxHtAccessFile) { + throw new Exception(sprintf('Could not create course repository dropbox subfolder access control file "%s"', $dropboxHtAccessFilePath)); + } + if (!fwrite( + $dropboxHtAccessFile, + "AuthName AllowLocalAccess +AuthType Basic + +order deny,allow +deny from all + +php_flag zlib.output_compression off" + )) { + throw new Exception(sprintf('Could not write to course repository dropbox subfolder access control file "%s"', $dropboxHtAccessFilePath)); + } + if (!fclose($dropboxHtAccessFile)) { + throw new Exception(sprintf('Could not close course repository dropbox subfolder access control file "%s"', $dropboxHtAccessFilePath)); + } + } + + private function createTools() + { + $toolReference = [ + [TOOL_COURSE_DESCRIPTION, 'course_description/index.php', 'info.gif', 'course_description', 'authoring'], + [TOOL_CALENDAR_EVENT, 'calendar/agenda.php', 'agenda.gif', 'agenda', 'interaction'], + [TOOL_DOCUMENT, 'document/document.php', 'folder_document.gif', 'documents', 'authoring'], + [TOOL_LEARNPATH, 'lp/lp_controller.php', 'scorms.gif', 'learning_path', 'authoring'], + [TOOL_LINK, 'link/link.php', 'links.gif', 'links', 'authoring'], + [TOOL_QUIZ, 'exercise/exercise.php', 'quiz.gif', 'quiz', 'authoring'], + [TOOL_ANNOUNCEMENT, 'announcements/announcements.php', 'valves.gif', 'announcements', 'authoring'], + [TOOL_FORUM, 'forum/index.php', 'forum.gif', 'forums', 'interaction'], + [TOOL_DROPBOX, 'dropbox/index.php', 'dropbox.gif', 'dropbox', 'interaction'], + [TOOL_USER, 'user/user.php', 'members.gif', 'users', 'interaction'], + [TOOL_GROUP, 'group/group.php', 'group.gif', 'groups', 'interaction'], + [TOOL_CHAT, 'chat/chat.php', 'chat.gif', 'chat', 'interaction'], + [TOOL_STUDENTPUBLICATION, 'work/work.php', 'works.gif', 'student_publications', 'interaction'], + [TOOL_SURVEY, 'survey/survey_list.php', 'survey.gif', 'survey', 'interaction'], + [TOOL_WIKI, 'wiki/index.php', 'wiki.gif', 'wiki', 'interaction'], + [TOOL_GRADEBOOK, 'gradebook/index.php', 'gradebook.gif', 'gradebook', 'authoring'], + [TOOL_GLOSSARY, 'glossary/index.php', 'glossary.gif', 'glossary', 'authoring'], + [TOOL_NOTEBOOK, 'notebook/index.php', 'notebook.gif', 'notebook', 'interaction'], + ]; + if (api_get_configuration_value('allow_portfolio_tool')) { + $toolReference[] = [TOOL_PORTFOLIO, 'portfolio/index.php', 'wiki_task.png', 'portfolio', 'interaction']; + } + $toolReference[] = [TOOL_ATTENDANCE, 'attendance/index.php', 'attendance.gif', 'attendances', 'authoring']; + $toolReference[] = + [TOOL_COURSE_PROGRESS, 'course_progress/index.php', 'course_progress.gif', 'course_progress', 'authoring']; + $counter = 1; + foreach ($toolReference as list($name, $link, $image, $key, $category)) { + (new CTool()) + ->setCourse($this) + ->setId($counter++) + ->setName($name) + ->setLink($link) + ->setImage($image) + ->setVisibility('true' === api_get_setting('course_create_active_tools', $key)) + ->setCategory($category); + } + if (api_get_setting('search_enabled') === 'true') { + (new CTool()) + ->setCourse($this) + ->setId($counter++) + ->setName(TOOL_SEARCH) + ->setLink('search/') + ->setImage('info.gif') + ->setVisibility('true' === api_get_setting('course_create_active_tools', 'enable_search')) + ->setCategory('authoring') + ->setAddress('search.gif'); + } + (new CTool()) + ->setCourse($this) + ->setId($counter++) + ->setName(TOOL_BLOGS) + ->setLink('blog/blog_admin.php') + ->setImage('blog_admin.gif') + ->setVisibility('true' === api_get_setting('course_create_active_tools', 'blogs')) + ->setCategory('admin') + ->setAdmin('1'); + foreach ([ + [TOOL_TRACKING, 'tracking/courseLog.php', 'statistics.gif'], + [TOOL_COURSE_SETTING, 'course_info/infocours.php', 'reference.gif'], + [TOOL_COURSE_MAINTENANCE, 'course_info/maintenance.php', 'backup.gif'], + ] as list($name, $link, $image)) { + (new CTool()) + ->setCourse($this) + ->setId($counter++) + ->setName($name) + ->setLink($link) + ->setImage($image) + ->setVisibility(false) + ->setCategory('admin') + ->setAdmin('1'); + } + } + + private function createSettings() + { + $settings = [ + 'email_alert_manager_on_new_doc' => ['default' => 0, 'category' => 'work'], + 'email_alert_on_new_doc_dropbox' => ['default' => 0, 'category' => 'dropbox'], + 'allow_user_edit_agenda' => ['default' => 0, 'category' => 'agenda'], + 'allow_user_edit_announcement' => ['default' => 0, 'category' => 'announcement'], + 'email_alert_manager_on_new_quiz' => [ + 'default' => (api_get_setting('email_alert_manager_on_new_quiz') === 'true') ? 1 : 0, + 'category' => 'quiz', + ], + 'allow_user_image_forum' => ['default' => 1, 'category' => 'forum'], + 'course_theme' => ['default' => '', 'category' => 'theme'], + 'allow_learning_path_theme' => ['default' => 1, 'category' => 'theme'], + 'allow_open_chat_window' => ['default' => 1, 'category' => 'chat'], + 'email_alert_to_teacher_on_new_user_in_course' => ['default' => 0, 'category' => 'registration'], + 'allow_user_view_user_list' => ['default' => 1, 'category' => 'user'], + 'display_info_advance_inside_homecourse' => ['default' => 1, 'category' => 'thematic_advance'], + 'email_alert_students_on_new_homework' => ['default' => 0, 'category' => 'work'], + 'enable_lp_auto_launch' => ['default' => 0, 'category' => 'learning_path'], + 'enable_exercise_auto_launch' => ['default' => 0, 'category' => 'exercise'], + 'enable_document_auto_launch' => ['default' => 0, 'category' => 'document'], + 'pdf_export_watermark_text' => ['default' => '', 'category' => 'learning_path'], + 'allow_public_certificates' => [ + 'default' => api_get_setting('allow_public_certificates') === 'true' ? 1 : '', + 'category' => 'certificates', + ], + 'documents_default_visibility' => ['default' => 'visible', 'category' => 'document'], + 'show_course_in_user_language' => ['default' => 2, 'category' => null], + 'email_to_teachers_on_new_work_feedback' => ['default' => 1, 'category' => null], + ]; + + $counter = 1; + foreach ($settings as $variable => $setting) { + (new CCourseSetting()) + ->setId($counter++) + ->setCourse($this) + ->setVariable($variable) + ->setValue($setting['default']) + ->setCategory($setting['category']); + } + } } diff --git a/src/Chamilo/CoreBundle/Entity/CourseRelUser.php b/src/Chamilo/CoreBundle/Entity/CourseRelUser.php index d9ad822f11e..d7710ed29c4 100644 --- a/src/Chamilo/CoreBundle/Entity/CourseRelUser.php +++ b/src/Chamilo/CoreBundle/Entity/CourseRelUser.php @@ -4,6 +4,8 @@ namespace Chamilo\CoreBundle\Entity; use Chamilo\UserBundle\Entity\User; +use Database; +use Doctrine\ORM\EntityRepository; use Doctrine\ORM\Mapping as ORM; /** @@ -103,6 +105,14 @@ public function __toString() return (string) $this->getCourse()->getCode(); } + /** + * @return EntityRepository + */ + public static function getRepository() + { + return Database::getManager()->getRepository('ChamiloCoreBundle:CourseRelUser'); + } + /** * @return int */ @@ -120,11 +130,14 @@ public function setId($id) } /** + * @param Course $course + * * @return $this */ - public function setCourse(Course $course) + public function setCourse($course) { $this->course = $course; + $this->course->getUsers()->add($this); return $this; } @@ -147,6 +160,7 @@ public function getCourse() public function setUser($user) { $this->user = $user; + $this->user->getCourses()->add($this); return $this; } @@ -243,10 +257,14 @@ public function isTutor() /** * @param bool $tutor + * + * @return CourseRelUser */ public function setTutor($tutor) { $this->tutor = $tutor; + + return $this; } /** diff --git a/src/Chamilo/CoreBundle/Entity/Listener/CourseListener.php b/src/Chamilo/CoreBundle/Entity/Listener/CourseListener.php deleted file mode 100644 index a72e9fca1b8..00000000000 --- a/src/Chamilo/CoreBundle/Entity/Listener/CourseListener.php +++ /dev/null @@ -1,40 +0,0 @@ -toolChain = $toolChain; - } - - /** - * new object : prePersist - * edited object: preUpdate. - */ - public function prePersist(Course $course, LifecycleEventArgs $args) - { - //$this->toolChain->addToolsInCourse($course); - /* - error_log('ddd'); - $course->setDescription( ' dq sdqs dqs dqs '); - - $args->getEntityManager()->persist($course); - $args->getEntityManager()->flush();*/ - } -} diff --git a/src/Chamilo/CoreBundle/Entity/Repository/ItemPropertyRepository.php b/src/Chamilo/CoreBundle/Entity/Repository/ItemPropertyRepository.php index 6e48e9f6a93..b8209ad01fb 100644 --- a/src/Chamilo/CoreBundle/Entity/Repository/ItemPropertyRepository.php +++ b/src/Chamilo/CoreBundle/Entity/Repository/ItemPropertyRepository.php @@ -213,7 +213,6 @@ public function subscribeUsersToItem( $newUserList = [] ) { $em = $this->getEntityManager(); - $user = $em->getRepository('ChamiloUserBundle:User'); $usersSubscribedToItem = $this->getUsersSubscribedToItem( $tool, @@ -248,7 +247,7 @@ public function subscribeUsersToItem( foreach ($newUserList as $userId) { if (!in_array($userId, $alreadyAddedUsers)) { - $userObj = $user->find($userId); + $userObj = api_get_user_entity($userId); $item = new CItemProperty($course); $item diff --git a/src/Chamilo/CoreBundle/Entity/Repository/SequenceRepository.php b/src/Chamilo/CoreBundle/Entity/Repository/SequenceRepository.php index f06a1b69954..8973f5bf471 100644 --- a/src/Chamilo/CoreBundle/Entity/Repository/SequenceRepository.php +++ b/src/Chamilo/CoreBundle/Entity/Repository/SequenceRepository.php @@ -53,19 +53,13 @@ public function getItem($itemId, $type) $resource = null; switch ($type) { case SequenceResource::COURSE_TYPE: - $repo = $this->getEntityManager()->getRepository('ChamiloCoreBundle:Course'); - + $resource = api_get_course_entity($itemId); break; case SequenceResource::SESSION_TYPE: - $repo = $this->getEntityManager()->getRepository('ChamiloCoreBundle:Session'); - + $resource = api_get_session_entity($itemId); break; } - if ($repo) { - $resource = $repo->find($itemId); - } - return $resource; } diff --git a/src/Chamilo/CoreBundle/Entity/Repository/SequenceResourceRepository.php b/src/Chamilo/CoreBundle/Entity/Repository/SequenceResourceRepository.php index 894bddcfd62..1dbfd9b144a 100644 --- a/src/Chamilo/CoreBundle/Entity/Repository/SequenceResourceRepository.php +++ b/src/Chamilo/CoreBundle/Entity/Repository/SequenceResourceRepository.php @@ -132,14 +132,10 @@ public function getRequirements($resourceId, $type) $resource = null; switch ($type) { case SequenceResource::SESSION_TYPE: - $repo = $em->getRepository('ChamiloCoreBundle:Session'); - $resource = $repo->find($vertexId); - + $resource = api_get_session_entity($vertexId); break; case SequenceResource::COURSE_TYPE: - $repo = $em->getRepository('ChamiloCoreBundle:Course'); - $resource = $repo->find($vertexId); - + $resource = api_get_course_entity($vertexId); break; } @@ -389,10 +385,10 @@ protected function findVerticesEdges(Vertices $verticesEdges, $type) $vertexId = $supVertex->getId(); switch ($type) { case SequenceResource::SESSION_TYPE: - $resource = $em->getRepository('ChamiloCoreBundle:Session')->find($vertexId); + $resource = api_get_session_entity($vertexId); break; case SequenceResource::COURSE_TYPE: - $resource = $em->getRepository('ChamiloCoreBundle:Course')->find($vertexId); + $resource = api_get_course_entity($vertexId); break; } diff --git a/src/Chamilo/CoreBundle/Entity/Session.php b/src/Chamilo/CoreBundle/Entity/Session.php index a3d10dc780d..dd742cdf72c 100644 --- a/src/Chamilo/CoreBundle/Entity/Session.php +++ b/src/Chamilo/CoreBundle/Entity/Session.php @@ -3,11 +3,17 @@ namespace Chamilo\CoreBundle\Entity; +use Chamilo\CourseBundle\Entity\CLp; use Chamilo\CourseBundle\Entity\CStudentPublication; use Chamilo\UserBundle\Entity\User; +use Database; +use Datetime; use Doctrine\Common\Collections\ArrayCollection; +use Doctrine\Common\Collections\Collection; use Doctrine\Common\Collections\Criteria; +use Doctrine\ORM\EntityRepository; use Doctrine\ORM\Mapping as ORM; +use Exception; //use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; //use Gedmo\Mapping\Annotation as Gedmo; @@ -60,7 +66,12 @@ class Session /** * @var ArrayCollection - * @ORM\OneToMany(targetEntity="SessionRelCourseRelUser", mappedBy="session", cascade={"persist"}, orphanRemoval=true) + * @ORM\OneToMany( + * targetEntity="SessionRelCourseRelUser", + * mappedBy="session", + * cascade={"persist"}, + * orphanRemoval=true + * ) */ protected $userCourseSubscriptions; @@ -140,42 +151,42 @@ class Session protected $promotionId; /** - * @var \DateTime + * @var DateTime * * @ORM\Column(name="display_start_date", type="datetime", nullable=true, unique=false) */ protected $displayStartDate; /** - * @var \DateTime + * @var DateTime * * @ORM\Column(name="display_end_date", type="datetime", nullable=true, unique=false) */ protected $displayEndDate; /** - * @var \DateTime + * @var DateTime * * @ORM\Column(name="access_start_date", type="datetime", nullable=true, unique=false) */ protected $accessStartDate; /** - * @var \DateTime + * @var DateTime * * @ORM\Column(name="access_end_date", type="datetime", nullable=true, unique=false) */ protected $accessEndDate; /** - * @var \DateTime + * @var DateTime * * @ORM\Column(name="coach_access_start_date", type="datetime", nullable=true, unique=false) */ protected $coachAccessStartDate; /** - * @var \DateTime + * @var DateTime * * @ORM\Column(name="coach_access_end_date", type="datetime", nullable=true, unique=false) */ @@ -191,9 +202,14 @@ class Session //protected $position; /** - * @ORM\OneToMany(targetEntity="Chamilo\CourseBundle\Entity\CItemProperty", mappedBy="session") + * @var Session[]|ArrayCollection + * @ORM\OneToMany( + * targetEntity="Chamilo\CourseBundle\Entity\CItemProperty", + * mappedBy="session", + * cascade={"persist","remove"}, + * ) */ - //protected $items; + protected $itemProperties; /** * @ORM\ManyToOne(targetEntity="Chamilo\UserBundle\Entity\User", inversedBy="sessionAsGeneralCoach") @@ -215,26 +231,42 @@ class Session /** * @var ArrayCollection - * @ORM\OneToMany(targetEntity="Chamilo\CourseBundle\Entity\CStudentPublication", mappedBy="session", cascade={"persist"}, orphanRemoval=true) + * @ORM\OneToMany( + * targetEntity="Chamilo\CourseBundle\Entity\CStudentPublication", + * mappedBy="session", + * cascade={"persist"}, + * orphanRemoval=true + * ) */ protected $studentPublications; + /** + * @var ArrayCollection|CLp[] + * + * @ORM\OneToMany( + * targetEntity="Chamilo\CourseBundle\Entity\CLp", + * mappedBy="session", + * cascade={"persist", "remove"} + * ) + */ + // protected $learningPaths; + /** * Constructor. */ public function __construct() { - $this->items = new ArrayCollection(); + $this->itemProperties = new ArrayCollection(); $this->nbrClasses = 0; $this->nbrUsers = 0; - $this->displayStartDate = new \DateTime(); - $this->displayEndDate = new \DateTime(); - $this->accessStartDate = new \DateTime(); - $this->accessEndDate = new \DateTime(); - $this->coachAccessStartDate = new \DateTime(); - $this->coachAccessEndDate = new \DateTime(); + $this->displayStartDate = new DateTime(); + $this->displayEndDate = new DateTime(); + $this->accessStartDate = new DateTime(); + $this->accessEndDate = new DateTime(); + $this->coachAccessStartDate = new DateTime(); + $this->coachAccessEndDate = new DateTime(); $this->visibility = 1; $this->courses = new ArrayCollection(); @@ -243,6 +275,7 @@ public function __construct() $this->showDescription = false; $this->category = null; $this->studentPublications = new ArrayCollection(); + $this->sendSubscriptionNotification = false; } /** @@ -253,6 +286,14 @@ public function __toString() return (string) $this->getName(); } + /** + * @return Repository\SessionRepository|EntityRepository + */ + public static function getRepository() + { + return Database::getManager()->getRepository('ChamiloCoreBundle:Session'); + } + /** * @return int */ @@ -334,9 +375,10 @@ public function addUser(SessionRelUser $user) } /** - * @param int $status + * @param int $status + * @param User $user */ - public function addUserInSession($status, User $user) + public function addUserInSession($status, $user) { $sessionRelUser = new SessionRelUser(); $sessionRelUser->setSession($this); @@ -347,9 +389,11 @@ public function addUserInSession($status, User $user) } /** + * @param SessionRelUser $subscription + * * @return bool */ - public function hasUser(SessionRelUser $subscription) + public function hasUser($subscription) { if ($this->getUsers()->count()) { $criteria = Criteria::create()->where( @@ -395,9 +439,11 @@ public function addCourses(SessionRelCourse $course) } /** + * @param Course $course + * * @return bool */ - public function hasCourse(Course $course) + public function hasCourse($course) { if ($this->getCourses()->count()) { $criteria = Criteria::create()->where( @@ -414,16 +460,13 @@ public function hasCourse(Course $course) /** * Check for existence of a relation (SessionRelCourse) between a course and this session. * + * @param Course $course + * * @return bool whether the course is related to this session */ - public function isRelatedToCourse(Course $course) + public function isRelatedToCourse($course) { - return !is_null( - \Database::getManager()->getRepository('ChamiloCoreBundle:SessionRelCourse')->findOneBy([ - 'session' => $this, - 'course' => $course, - ]) - ); + return $this->courses->contains($course); } /** @@ -443,8 +486,11 @@ public function removeCourses($course) /** * Remove course subscription for a user. * If user status in session is student, then decrease number of course users. + * + * @param User $user + * @param Course $course */ - public function removeUserCourseSubscription(User $user, Course $course) + public function removeUserCourseSubscription($user, $course) { /** @var SessionRelCourseRelUser $courseSubscription */ foreach ($this->userCourseSubscriptions as $i => $courseSubscription) { @@ -464,12 +510,13 @@ public function removeUserCourseSubscription(User $user, Course $course) } /** - * @param int $status if not set it will check if the user is registered - * with any status + * @param User $user + * @param Course $course + * @param int $status if not set it will check if the user is registered with any status * * @return bool */ - public function hasUserInCourse(User $user, Course $course, $status = null) + public function hasUserInCourse($user, $course, $status = null) { $relation = $this->getUserInCourse($user, $course, $status); @@ -477,27 +524,35 @@ public function hasUserInCourse(User $user, Course $course, $status = null) } /** + * @param User $user + * @param Course $course + * * @return bool */ - public function hasStudentInCourse(User $user, Course $course) + public function hasStudentInCourse($user, $course) { return $this->hasUserInCourse($user, $course, self::STUDENT); } /** + * @param User $user + * @param Course $course + * * @return bool */ - public function hasCoachInCourseWithStatus(User $user, Course $course) + public function hasCoachInCourseWithStatus($user, $course) { return $this->hasUserInCourse($user, $course, self::COACH); } /** + * @param User $user + * @param Course $course * @param string $status * - * @return \Doctrine\Common\Collections\Collection|static + * @return Collection|static */ - public function getUserInCourse(User $user, Course $course, $status = null) + public function getUserInCourse($user, $course, $status = null) { $criteria = Criteria::create()->where( Criteria::expr()->eq('course', $course) @@ -709,7 +764,7 @@ public function getPromotionId() /** * Set displayStartDate. * - * @param \DateTime $displayStartDate + * @param DateTime $displayStartDate * * @return Session */ @@ -723,7 +778,7 @@ public function setDisplayStartDate($displayStartDate) /** * Get displayStartDate. * - * @return \DateTime + * @return DateTime */ public function getDisplayStartDate() { @@ -733,7 +788,7 @@ public function getDisplayStartDate() /** * Set displayEndDate. * - * @param \DateTime $displayEndDate + * @param DateTime $displayEndDate * * @return Session */ @@ -747,7 +802,7 @@ public function setDisplayEndDate($displayEndDate) /** * Get displayEndDate. * - * @return \DateTime + * @return DateTime */ public function getDisplayEndDate() { @@ -757,7 +812,7 @@ public function getDisplayEndDate() /** * Set accessStartDate. * - * @param \DateTime $accessStartDate + * @param DateTime $accessStartDate * * @return Session */ @@ -771,7 +826,7 @@ public function setAccessStartDate($accessStartDate) /** * Get accessStartDate. * - * @return \DateTime + * @return DateTime */ public function getAccessStartDate() { @@ -781,7 +836,7 @@ public function getAccessStartDate() /** * Set accessEndDate. * - * @param \DateTime $accessEndDate + * @param DateTime $accessEndDate * * @return Session */ @@ -795,7 +850,7 @@ public function setAccessEndDate($accessEndDate) /** * Get accessEndDate. * - * @return \DateTime + * @return DateTime */ public function getAccessEndDate() { @@ -805,7 +860,7 @@ public function getAccessEndDate() /** * Set coachAccessStartDate. * - * @param \DateTime $coachAccessStartDate + * @param DateTime $coachAccessStartDate * * @return Session */ @@ -819,7 +874,7 @@ public function setCoachAccessStartDate($coachAccessStartDate) /** * Get coachAccessStartDate. * - * @return \DateTime + * @return DateTime */ public function getCoachAccessStartDate() { @@ -829,7 +884,7 @@ public function getCoachAccessStartDate() /** * Set coachAccessEndDate. * - * @param \DateTime $coachAccessEndDate + * @param DateTime $coachAccessEndDate * * @return Session */ @@ -843,7 +898,7 @@ public function setCoachAccessEndDate($coachAccessEndDate) /** * Get coachAccessEndDate. * - * @return \DateTime + * @return DateTime */ public function getCoachAccessEndDate() { @@ -909,7 +964,7 @@ public static function getStatusList() */ public function isActive() { - $now = new \Datetime('now'); + $now = new Datetime('now'); return $now > $this->getAccessStartDate(); } @@ -923,8 +978,8 @@ public function isActive() public function isCurrentlyAccessible() { try { - $now = new \Datetime(); - } catch (\Exception $exception) { + $now = new Datetime(); + } catch (Exception $exception) { return false; } @@ -990,9 +1045,11 @@ public function addUserCourseSubscription(SessionRelCourseRelUser $subscription) } /** + * @param Course $course + * * @return SessionRelCourse */ - public function getCourseSubscription(Course $course) + public function getCourseSubscription($course) { $criteria = Criteria::create()->where( Criteria::expr()->eq('course', $course) @@ -1010,9 +1067,11 @@ public function getCourseSubscription(Course $course) * Add a user course subscription. * If user status in session is student, then increase number of course users. * - * @param int $status + * @param int $status + * @param User $user + * @param Course $course */ - public function addUserInCourse($status, User $user, Course $course) + public function addUserInCourse($status, $user, $course) { $userRelCourseRelSession = new SessionRelCourseRelUser(); $userRelCourseRelSession->setCourse($course); @@ -1031,9 +1090,11 @@ public function addUserInCourse($status, User $user, Course $course) } /** + * @param SessionRelCourseRelUser $subscription + * * @return bool */ - public function hasUserCourseSubscription(SessionRelCourseRelUser $subscription) + public function hasUserCourseSubscription($subscription) { if ($this->getUserCourseSubscriptions()->count()) { $criteria = Criteria::create()->where( @@ -1060,9 +1121,11 @@ public function getCurrentCourse() } /** + * @param Course $course + * * @return $this */ - public function setCurrentCourse(Course $course) + public function setCurrentCourse($course) { // If the session is registered in the course session list. if ($this->getCourses()->contains($course->getId())) { @@ -1077,7 +1140,7 @@ public function setCurrentCourse(Course $course) * * @param bool $sendNotification * - * @return \Chamilo\CoreBundle\Entity\Session + * @return Session */ public function setSendSubscriptionNotification($sendNotification) { @@ -1099,11 +1162,12 @@ public function getSendSubscriptionNotification() /** * Get user from course by status. * - * @param int $status + * @param Course $course + * @param int $status * - * @return \Doctrine\Common\Collections\ArrayCollection|\Doctrine\Common\Collections\Collection + * @return ArrayCollection|Collection */ - public function getUserCourseSubscriptionsByStatus(Course $course, $status) + public function getUserCourseSubscriptionsByStatus($course, $status) { $criteria = Criteria::create() ->where( @@ -1117,9 +1181,11 @@ public function getUserCourseSubscriptionsByStatus(Course $course, $status) } /** + * @param ArrayCollection $studentPublications + * * @return Session */ - public function setStudentPublications(ArrayCollection $studentPublications) + public function setStudentPublications($studentPublications) { $this->studentPublications = new ArrayCollection(); @@ -1131,9 +1197,11 @@ public function setStudentPublications(ArrayCollection $studentPublications) } /** + * @param CStudentPublication $studentPublication + * * @return Session */ - public function addStudentPublication(CStudentPublication $studentPublication) + public function addStudentPublication($studentPublication) { $this->studentPublications[] = $studentPublication; @@ -1151,9 +1219,11 @@ public function getStudentPublications() } /** + * @param Course $course + * * @return ArrayCollection */ - public function getUsersSubscriptionsInCourse(Course $course) + public function getUsersSubscriptionsInCourse($course) { $criteria = Criteria::create() ->where( @@ -1163,6 +1233,11 @@ public function getUsersSubscriptionsInCourse(Course $course) return $this->userCourseSubscriptions->matching($criteria); } + public function getItemProperties() + { + return $this->itemProperties; + } + /** * @return int */ @@ -1182,4 +1257,12 @@ public function getUsersSubscriptionsInCourse(Course $course) return $this; }*/ + + /** + * @return CLp[]|ArrayCollection + */ + /*public function getLearningPaths() + { + return $this->learningPaths; + }*/ } diff --git a/src/Chamilo/CoreBundle/Entity/SessionCategory.php b/src/Chamilo/CoreBundle/Entity/SessionCategory.php index f5c41be87d8..7260221b4ce 100644 --- a/src/Chamilo/CoreBundle/Entity/SessionCategory.php +++ b/src/Chamilo/CoreBundle/Entity/SessionCategory.php @@ -14,7 +14,7 @@ class SessionCategory { /** - * @ORM\ManyToOne(targetEntity="AccessUrl", inversedBy="sessionCategory", cascade={"persist"}) + * @ORM\ManyToOne(targetEntity="AccessUrl", inversedBy="sessionCategories", cascade={"persist"}) * @ORM\JoinColumn(name="access_url_id", referencedColumnName="id") */ protected $url; diff --git a/src/Chamilo/CoreBundle/Entity/UserCourseCategory.php b/src/Chamilo/CoreBundle/Entity/UserCourseCategory.php index 7ba359a9b53..f8eced5dedb 100644 --- a/src/Chamilo/CoreBundle/Entity/UserCourseCategory.php +++ b/src/Chamilo/CoreBundle/Entity/UserCourseCategory.php @@ -3,6 +3,8 @@ namespace Chamilo\CoreBundle\Entity; +use Database; +use Doctrine\ORM\EntityRepository; use Doctrine\ORM\Mapping as ORM; /** @@ -43,6 +45,14 @@ class UserCourseCategory */ protected $sort; + /** + * @return EntityRepository + */ + public static function getRepository() + { + return Database::getManager()->getRepository('ChamiloCoreBundle:UserCourseCategory'); + } + /** * Set userId. * diff --git a/src/Chamilo/CourseBundle/Entity/CCourseSetting.php b/src/Chamilo/CourseBundle/Entity/CCourseSetting.php index 50577716c6c..126e14e50c2 100644 --- a/src/Chamilo/CourseBundle/Entity/CCourseSetting.php +++ b/src/Chamilo/CourseBundle/Entity/CCourseSetting.php @@ -3,6 +3,7 @@ namespace Chamilo\CourseBundle\Entity; +use Chamilo\CoreBundle\Entity\Course; use Doctrine\ORM\Mapping as ORM; /** @@ -97,6 +98,19 @@ class CCourseSetting */ protected $subkeytext; + /** + * @var Course + * + * @ORM\ManyToOne(targetEntity="Chamilo\CoreBundle\Entity\Course", inversedBy="settings") + * @ORM\JoinColumn(name="c_id", referencedColumnName="id") + */ + protected $course; + + public function __construct() + { + $this->title = ''; + } + /** * Set variable. * @@ -316,6 +330,8 @@ public function getId() /** * Set cId. * + * @deprecated use setCourse wherever possible + * * @param int $cId * * @return CCourseSetting @@ -323,6 +339,7 @@ public function getId() public function setCId($cId) { $this->cId = $cId; + $this->setCourse(api_get_course_entity($cId)); return $this; } @@ -336,4 +353,25 @@ public function getCId() { return $this->cId; } + + /** + * @return Course + */ + public function getCourse() + { + return $this->course; + } + + /** + * @param Course $course + * + * @return $this + */ + public function setCourse($course) + { + $this->course = $course; + $this->course->getSettings()->add($this); + + return $this; + } } diff --git a/src/Chamilo/CourseBundle/Entity/CDocument.php b/src/Chamilo/CourseBundle/Entity/CDocument.php index f65081b386e..a657775a5f1 100644 --- a/src/Chamilo/CourseBundle/Entity/CDocument.php +++ b/src/Chamilo/CourseBundle/Entity/CDocument.php @@ -3,7 +3,14 @@ namespace Chamilo\CourseBundle\Entity; +use Chamilo\CoreBundle\Entity\Course; +use Database; +use Doctrine\ORM\EntityRepository; use Doctrine\ORM\Mapping as ORM; +use Doctrine\ORM\OptimisticLockException; +use Doctrine\ORM\ORMException; +use Doctrine\ORM\TransactionRequiredException; +use Exception; /** * CDocument. @@ -15,6 +22,7 @@ * } * ) * @ORM\Entity + * @ORM\HasLifecycleCallbacks */ class CDocument { @@ -90,6 +98,179 @@ class CDocument */ protected $sessionId; + /** + * @var Course + * + * @ORM\ManyToOne(targetEntity="Chamilo\CoreBundle\Entity\Course", inversedBy="documents") + * @ORM\JoinColumn(name="c_id", referencedColumnName="id") + */ + protected $course; + + public function __construct() + { + $this->size = 0; + $this->readonly = false; + $this->sessionId = 0; + } + + /** + * @return EntityRepository + */ + public static function getRepository() + { + return Database::getManager()->getRepository('ChamiloCourseBundle:CDocument'); + } + + /** + * Instantiates a new CDocument by copying a file to the course. + * + * @param string $filePath the source file to be copied to the course directory + * @param Course $course the course for which the document is being created + * @param string $documentPath the future document's relative path + * @param string $title a title for the document + * + * @throws ORMException + * @throws OptimisticLockException + * @throws TransactionRequiredException + * @throws Exception + * + * @return CDocument + */ + public static function fromFile($filePath, $course, $documentPath, $title) + { + $instance = (new static()) + ->setCourse($course) + ->setPath($documentPath) + ->setTitle($title); + $absolutePath = $instance->getAbsolutePath(); + if (!copy($filePath, $absolutePath)) { + throw new Exception(sprintf('Could not copy course document file %s to %s', $filePath, $absolutePath)); + } + + return $instance; + } + + /** + * @return Course + */ + public function getCourse() + { + return $this->course; + } + + /** + * @param Course $course + * + * @return $this + */ + public function setCourse($course) + { + $this->course = $course; + $this->course->getDocuments()->add($this); + + return $this; + } + + /** + * Builds the document's absolute path from its course's own path and its (relative) path. + * + * @throws OptimisticLockException + * @throws TransactionRequiredException + * @throws ORMException + * @throws Exception + * + * @return string the document's absolute path + */ + public function getAbsolutePath() + { + if (is_null($this->course) && $this->cId) { + $this->course = api_get_course_entity($this->cId); + } + if (is_null($this->course)) { + throw new Exception('this document does not have a course yet'); + } + + return sprintf( + '%s/document/%s', + $this->course->getAbsolutePath(), + $this->path + ); + } + + /** + * Makes sure the actual file exists. + * Records the file type. + * Computes document file size if needed. + * + * @ORM\PrePersist + * + * @throws Exception + */ + public function prePersist() + { + $absolutePath = $this->getAbsolutePath(); + if (!file_exists($absolutePath)) { + throw new Exception('Cannot persist a document without an existing file'); + } + if (empty($this->filetype)) { + $type = filetype($absolutePath); + switch ($type) { + case 'dir': + $this->filetype = 'folder'; + break; + case 'file': + case 'link': + $this->filetype = $type; + break; + default: + throw new Exception('unsupported file type: '.$type); + } + } + if (0 === $this->size && 'file' == $this->filetype) { + $this->size = filesize($absolutePath); + } + } + + /** + * If id is null, copies iid to id and writes again. + * + * @ORM\PostPersist + * + * @throws Exception + */ + public function postPersist() + { + if (is_null($this->id)) { // keep this test to avoid recursion + $this->id = $this->iid; + Database::getManager()->persist($this); + Database::getManager()->flush($this); + } + } + + /** + * Removes the actual file, folder or link. + * + * @ORM\PostRemove + */ + public function postRemove() + { + $absolutePath = ''; + try { + $absolutePath = $this->getAbsolutePath(); + } catch (Exception $exception) { + error_log($exception->getMessage()); + } + if (!empty($absolutePath) && file_exists($absolutePath)) { + if ('folder' === $this->filetype && is_dir($absolutePath)) { + rmdir($absolutePath); + } elseif ('file' === $this->filetype && is_file($absolutePath)) { + unlink($absolutePath); + } elseif ('link' === $this->filetype && is_link($absolutePath)) { + unlink($absolutePath); + } + } + } + /** * Set path. * @@ -285,6 +466,8 @@ public function getId() /** * Set cId. * + * @deprecated use setCourse wherever possible + * * @param int $cId * * @return CDocument @@ -292,6 +475,7 @@ public function getId() public function setCId($cId) { $this->cId = $cId; + $this->setCourse(api_get_course_entity($cId)); return $this; } diff --git a/src/Chamilo/CourseBundle/Entity/CForumForum.php b/src/Chamilo/CourseBundle/Entity/CForumForum.php index fd95842cb1f..7ec55b4c5f3 100644 --- a/src/Chamilo/CourseBundle/Entity/CForumForum.php +++ b/src/Chamilo/CourseBundle/Entity/CForumForum.php @@ -3,7 +3,12 @@ namespace Chamilo\CourseBundle\Entity; +use Chamilo\CoreBundle\Entity\Course; +use Database; +use DateTime; +use Doctrine\ORM\EntityRepository; use Doctrine\ORM\Mapping as ORM; +use Doctrine\ORM\OptimisticLockException; /** * CForumForum. @@ -15,6 +20,7 @@ * } * ) * @ORM\Entity + * @ORM\HasLifecycleCallbacks */ class CForumForum { @@ -168,14 +174,14 @@ class CForumForum protected $forumImage; /** - * @var \DateTime + * @var DateTime * * @ORM\Column(name="start_time", type="datetime", nullable=true) */ protected $startTime; /** - * @var \DateTime + * @var DateTime * * @ORM\Column(name="end_time", type="datetime", nullable=true) */ @@ -195,6 +201,66 @@ class CForumForum */ protected $moderated; + /** + * @var Course + * + * @ORM\ManyToOne(targetEntity="Chamilo\CoreBundle\Entity\Course", inversedBy="forums") + * @ORM\JoinColumn(name="c_id", referencedColumnName="id") + */ + protected $course; + + public function __construct() + { + $this->forumId = 0; + $this->locked = 0; + $this->sessionId = 0; + $this->forumImage = ''; + $this->lpId = 0; + } + + /** + * @return EntityRepository + */ + public static function getRepository() + { + return Database::getManager()->getRepository('ChamiloCourseBundle:CForumForum'); + } + + /** + * @ORM\PostPersist + * + * @throws OptimisticLockException + */ + public function postPersist() + { + if (is_null($this->forumId)) { + $this->forumId = $this->iid; + Database::getManager()->persist($this); + Database::getManager()->flush($this); + } + } + + /** + * @return Course + */ + public function getCourse() + { + return $this->course; + } + + /** + * @param Course $course + * + * @return $this + */ + public function setCourse($course) + { + $this->course = $course; + $this->course->getForums()->add($this); + + return $this; + } + /** * Set forumTitle. * @@ -626,7 +692,7 @@ public function getForumImage() /** * Set startTime. * - * @param \DateTime $startTime + * @param DateTime $startTime * * @return CForumForum */ @@ -640,7 +706,7 @@ public function setStartTime($startTime) /** * Get startTime. * - * @return \DateTime + * @return DateTime */ public function getStartTime() { @@ -650,7 +716,7 @@ public function getStartTime() /** * Set endTime. * - * @param \DateTime $endTime + * @param DateTime $endTime * * @return CForumForum */ @@ -664,7 +730,7 @@ public function setEndTime($endTime) /** * Get endTime. * - * @return \DateTime + * @return DateTime */ public function getEndTime() { @@ -698,6 +764,8 @@ public function getForumId() /** * Set cId. * + * @deprecated use setCourse wherever possible + * * @param int $cId * * @return CForumForum @@ -705,6 +773,7 @@ public function getForumId() public function setCId($cId) { $this->cId = $cId; + $this->setCourse(api_get_course_entity($cId)); return $this; } diff --git a/src/Chamilo/CourseBundle/Entity/CGroupInfo.php b/src/Chamilo/CourseBundle/Entity/CGroupInfo.php index b37a3c2f87d..69e23854117 100644 --- a/src/Chamilo/CourseBundle/Entity/CGroupInfo.php +++ b/src/Chamilo/CourseBundle/Entity/CGroupInfo.php @@ -3,6 +3,8 @@ namespace Chamilo\CourseBundle\Entity; +use Database; +use Doctrine\ORM\EntityRepository; use Doctrine\ORM\Mapping as ORM; /** @@ -154,6 +156,14 @@ class CGroupInfo */ protected $sessionId; + /** + * @return EntityRepository + */ + public static function getRepository() + { + return Database::getManager()->getRepository('ChamiloCourseBundle:CGroupInfo'); + } + /** * @var int needed for setting['group_document_access'] * diff --git a/src/Chamilo/CourseBundle/Entity/CItemProperty.php b/src/Chamilo/CourseBundle/Entity/CItemProperty.php index f66ddf81ea0..d5ca5113cae 100644 --- a/src/Chamilo/CourseBundle/Entity/CItemProperty.php +++ b/src/Chamilo/CourseBundle/Entity/CItemProperty.php @@ -4,14 +4,23 @@ namespace Chamilo\CourseBundle\Entity; use Chamilo\CoreBundle\Entity\Course; +use Chamilo\CoreBundle\Entity\Repository\ItemPropertyRepository; +use Chamilo\CoreBundle\Entity\Session; use Chamilo\UserBundle\Entity\User; +use Database; +use DateTime; +use DateTimeZone; +use Doctrine\ORM\EntityRepository; use Doctrine\ORM\Mapping as ORM; +use Doctrine\ORM\OptimisticLockException; +use Exception; /** * CItemProperty. * * @ORM\Table(name="c_item_property", indexes={@ORM\Index(name="idx_item_property_toolref", columns={"tool", "ref"})}) * @ORM\Entity(repositoryClass="Chamilo\CoreBundle\Entity\Repository\ItemPropertyRepository") + * @ORM\HasLifecycleCallbacks */ class CItemProperty { @@ -31,13 +40,19 @@ class CItemProperty */ protected $id; - /** //, inversedBy="users",. - * @ORM\ManyToOne(targetEntity="Chamilo\CoreBundle\Entity\Course", cascade={"persist"}) - * @ORM\JoinColumn(name="c_id", referencedColumnName="id") + /** + * @var Course + * + * @ORM\ManyToOne( + * targetEntity="Chamilo\CoreBundle\Entity\Course", + * inversedBy="itemProperties", + * cascade={"persist"} + * ) + * @ORM\JoinColumn(name="c_id", referencedColumnName="id", nullable=true) */ protected $course; - /** //, inversedBy="users",. + /** * @ORM\ManyToOne(targetEntity="Chamilo\CourseBundle\Entity\CGroupInfo", cascade={"persist"}) * @ORM\JoinColumn(name="to_group_id", referencedColumnName="iid") */ @@ -55,9 +70,15 @@ class CItemProperty */ protected $insertUser; - /** //, inversedBy="users",. - * @ORM\ManyToOne(targetEntity="Chamilo\CoreBundle\Entity\Session", cascade={"persist"}) - * @ORM\JoinColumn(name="session_id", referencedColumnName="id") + /** + * @var Session + * + * @ORM\ManyToOne( + * targetEntity="Chamilo\CoreBundle\Entity\Session", + * inversedBy="itemProperties", + * cascade={"persist"} + * ) + * @ORM\JoinColumn(name="session_id", referencedColumnName="id", nullable=true) */ protected $session; @@ -69,14 +90,14 @@ class CItemProperty protected $tool; /** - * @var \DateTime + * @var DateTime * * @ORM\Column(name="insert_date", type="datetime", nullable=false) */ protected $insertDate; /** - * @var \DateTime + * @var DateTime * * @ORM\Column(name="lastedit_date", type="datetime", nullable=false) */ @@ -111,14 +132,14 @@ class CItemProperty protected $visibility; /** - * @var \DateTime + * @var DateTime * * @ORM\Column(name="start_visible", type="datetime", nullable=true) */ protected $startVisible; /** - * @var \DateTime + * @var DateTime * * @ORM\Column(name="end_visible", type="datetime", nullable=true) */ @@ -126,13 +147,52 @@ class CItemProperty /** * CItemProperty constructor. + * + * @param Course $course + * + * @throws Exception */ - public function __construct(Course $course) + public function __construct($course) { $this->visibility = 1; - $this->course = $course; - $this->insertDate = new \DateTime('now', new \DateTimeZone('UTC')); - $this->lasteditDate = new \DateTime('now', new \DateTimeZone('UTC')); + $this->setCourse($course); + $this->insertDate = new DateTime('now', new DateTimeZone('UTC')); + $this->lasteditDate = new DateTime('now', new DateTimeZone('UTC')); + $this->lasteditUserId = api_get_user_id() ?: api_get_anonymous_id(); + } + + /** + * @return ItemPropertyRepository|EntityRepository + */ + public static function getRepository() + { + return Database::getManager()->getRepository('ChamiloCourseBundle:CItemProperty'); + } + + /** + * @ORM\PreUpdate + * + * @throws Exception + */ + public function preUpdate() + { + $this->lasteditDate = new DateTime('now', new DateTimeZone('UTC')); + } + + /** + * Copies iid to id if not set yet. + * + * @ORM\PostPersist + * + * @throws OptimisticLockException + */ + public function postPersist() + { + if (is_null($this->id)) { + $this->id = $this->iid; + Database::getManager()->persist($this); + Database::getManager()->flush(); + } } /** @@ -162,7 +222,7 @@ public function getTool() /** * Set insertDate. * - * @param \DateTime $insertDate + * @param DateTime $insertDate * * @return CItemProperty */ @@ -176,7 +236,7 @@ public function setInsertDate($insertDate) /** * Get insertDate. * - * @return \DateTime + * @return DateTime */ public function getInsertDate() { @@ -186,9 +246,11 @@ public function getInsertDate() /** * Set lasteditDate. * + * @param DateTime $lasteditDate + * * @return CItemProperty */ - public function setLasteditDate(\DateTime $lasteditDate) + public function setLasteditDate($lasteditDate) { $this->lasteditDate = $lasteditDate; @@ -198,7 +260,7 @@ public function setLasteditDate(\DateTime $lasteditDate) /** * Get lasteditDate. * - * @return \DateTime + * @return DateTime */ public function getLasteditDate() { @@ -304,11 +366,11 @@ public function getVisibility() /** * Set startVisible. * - * @param \DateTime $startVisible + * @param DateTime $startVisible * * @return CItemProperty */ - public function setStartVisible(\DateTime $startVisible = null) + public function setStartVisible(DateTime $startVisible = null) { $this->startVisible = $startVisible; @@ -318,7 +380,7 @@ public function setStartVisible(\DateTime $startVisible = null) /** * Get startVisible. * - * @return \DateTime + * @return DateTime */ public function getStartVisible() { @@ -328,11 +390,11 @@ public function getStartVisible() /** * Set endVisible. * - * @param \DateTime $endVisible + * @param DateTime $endVisible * * @return CItemProperty */ - public function setEndVisible(\DateTime $endVisible = null) + public function setEndVisible(DateTime $endVisible = null) { $this->endVisible = $endVisible; @@ -342,7 +404,7 @@ public function setEndVisible(\DateTime $endVisible = null) /** * Get endVisible. * - * @return \DateTime + * @return DateTime */ public function getEndVisible() { @@ -389,6 +451,9 @@ public function getSession() public function setSession($session) { $this->session = $session; + if (!is_null($session)) { + $session->getItemProperties()->add($this); + } return $this; } @@ -409,6 +474,7 @@ public function getCourse() public function setCourse($course) { $this->course = $course; + $this->course->getItemProperties()->add($this); return $this; } @@ -462,9 +528,11 @@ public function getInsertUser() } /** + * @param User $insertUser + * * @return $this */ - public function setInsertUser(User $insertUser) + public function setInsertUser($insertUser) { $this->insertUser = $insertUser; $this->lasteditUserId = $insertUser->getId(); diff --git a/src/Chamilo/CourseBundle/Entity/CLink.php b/src/Chamilo/CourseBundle/Entity/CLink.php index 6469587428b..eb787696879 100644 --- a/src/Chamilo/CourseBundle/Entity/CLink.php +++ b/src/Chamilo/CourseBundle/Entity/CLink.php @@ -3,7 +3,11 @@ namespace Chamilo\CourseBundle\Entity; +use Chamilo\CoreBundle\Entity\Course; +use Database; +use Doctrine\ORM\EntityRepository; use Doctrine\ORM\Mapping as ORM; +use Doctrine\ORM\OptimisticLockException; /** * CLink. @@ -16,6 +20,7 @@ * } * ) * @ORM\Entity + * @ORM\HasLifecycleCallbacks */ class CLink { @@ -98,6 +103,66 @@ class CLink */ protected $sessionId; + /** + * @var Course + * @ORM\ManyToOne(targetEntity="Chamilo\CoreBundle\Entity\Course", inversedBy="links") + * @ORM\JoinColumn(name="c_id", referencedColumnName="id") + */ + protected $course; + + public function __construct() + { + $this->description = ''; + $this->categoryId = 0; + $this->displayOrder = 0; + $this->onHomepage = '0'; + $this->target = '_self'; + $this->sessionId = 0; + } + + /** + * @return EntityRepository + */ + public static function getRepository() + { + return Database::getManager()->getRepository('ChamiloCourseBundle:CLink'); + } + + /** + * @return Course + */ + public function getCourse() + { + return $this->course; + } + + /** + * @param Course $course + * + * @return $this + */ + public function setCourse($course) + { + $this->course = $course; + $this->course->getLinks()->add($this); + + return $this; + } + + /** + * @ORM\PostPersist + * + * @throws OptimisticLockException + */ + public function postPersist() + { + if (is_null($this->id)) { + $this->id = $this->iid; + Database::getManager()->persist($this); + Database::getManager()->flush($this); + } + } + /** * Set url. * @@ -317,6 +382,8 @@ public function getId() /** * Set cId. * + * @deprecated use setCourse wherever possible + * * @param int $cId * * @return CLink @@ -324,6 +391,7 @@ public function getId() public function setCId($cId) { $this->cId = $cId; + $this->setCourse(api_get_course_entity($cId)); return $this; } diff --git a/src/Chamilo/CourseBundle/Entity/CLp.php b/src/Chamilo/CourseBundle/Entity/CLp.php index 848adbe2e88..25abde7e1b3 100644 --- a/src/Chamilo/CourseBundle/Entity/CLp.php +++ b/src/Chamilo/CourseBundle/Entity/CLp.php @@ -3,7 +3,16 @@ namespace Chamilo\CourseBundle\Entity; +use Chamilo\CoreBundle\Entity\Course; +use Chamilo\CoreBundle\Entity\Session; +use Database; +use DateTime; +use DateTimeZone; +use Doctrine\Common\Collections\ArrayCollection; +use Doctrine\ORM\EntityRepository; use Doctrine\ORM\Mapping as ORM; +use Doctrine\ORM\OptimisticLockException; +use Exception; /** * CLp. @@ -16,6 +25,7 @@ * } * ) * @ORM\Entity + * @ORM\HasLifecycleCallbacks */ class CLp { @@ -232,28 +242,28 @@ class CLp protected $subscribeUsers; /** - * @var \DateTime + * @var DateTime * * @ORM\Column(name="created_on", type="datetime", nullable=false) */ protected $createdOn; /** - * @var \DateTime + * @var DateTime * * @ORM\Column(name="modified_on", type="datetime", nullable=false) */ protected $modifiedOn; /** - * @var \DateTime + * @var DateTime * * @ORM\Column(name="publicated_on", type="datetime", nullable=true) */ protected $publicatedOn; /** - * @var \DateTime + * @var DateTime * * @ORM\Column(name="expired_on", type="datetime", nullable=true) */ @@ -266,20 +276,240 @@ class CLp */ protected $accumulateScormTime; + /** + * @var Course + * @ORM\ManyToOne( + * targetEntity="Chamilo\CoreBundle\Entity\Course", + * inversedBy="learningPaths", + * cascade={"persist"} + * ) + * @ORM\JoinColumn(name="c_id", referencedColumnName="id") + */ + protected $course; + + /** + * @var Session + * @ORM\ManyToOne(targetEntity="Chamilo\CoreBundle\Entity\Session", inversedBy="learningPaths") + * @ORM\JoinColumn(name="session_id", referencedColumnName="id") + */ + /*protected $session;*/ + + /** + * @var CLpCategory + * + * @ORM\ManyToOne(targetEntity="Chamilo\CourseBundle\Entity\CLpCategory", inversedBy="learningPaths") + * @ORM\JoinColumn(name="category_id", referencedColumnName="iid") + */ + /*protected $category;*/ + + /** + * @var ArrayCollection|CLpItem[] + * + * @ORM\OneToMany( + * targetEntity="CLpItem", + * mappedBy="learningPath", + * orphanRemoval=true + * ) + */ + protected $items; + /** * Constructor. + * + * @throws Exception */ public function __construct() { + $this->sessionId = api_get_session_id(); + $this->categoryId = 0; $this->defaultViewMod = 'embedded'; $this->defaultEncoding = 'UTF-8'; $this->displayOrder = 0; $this->contentLocal = 'local'; $this->preventReinit = true; $this->useMaxScore = 1; - $this->createdOn = new \DateTime(); + $this->lpType = 1; + $this->path = ''; + $this->forceCommit = false; + $this->contentMaker = 'Chamilo'; + $this->contentLicense = ''; + $this->jsLib = ''; + $this->debug = false; + $this->theme = ''; + $this->previewImage = ''; + $this->author = ''; + $this->prerequisite = 0; + $this->hideTocFrame = false; + $this->seriousgameMode = false; + $this->autolaunch = 0; + $this->maxAttempts = 0; + $this->subscribeUsers = 0; + $this->createdOn = new DateTime('now', new DateTimeZone('utc')); + $this->modifiedOn = new DateTime('now', new DateTimeZone('utc')); + $this->accumulateScormTime = 1; + $this->items = new ArrayCollection(); + } + + public function __toString() + { + return sprintf('learning path %s ("%s") of %s', $this->id, $this->name, $this->course->__toString()); + } + + /** + * @return EntityRepository + */ + public static function getRepository() + { + return Database::getManager()->getRepository('ChamiloCourseBundle:CLp'); + } + + /** + * If course is not yet set, take the current course. + * Appends a number to name if it is already taken by another learning path in the same course. + * Computes displayOrder if still zéro. + * + * @ORM\PrePersist + * + * @throws Exception + */ + public function prePersist() + { + if (is_null($this->course)) { + $this->course = api_get_course_entity(); + if (is_null($this->course)) { + throw new Exception('cannot persist a leaning path without course'); + } + } + + $coursesOtherLearningPaths = $this->course->getLearningPaths()->filter(function ($lp) { + return $this !== $lp; + }); + + $originalName = $this->name; + $counter = 0; + while ($coursesOtherLearningPaths->exists(function ($key, $lp) { + return $lp->name === $this->name; + })) { + $counter++; + $this->name = sprintf('%s - %d', $originalName, $counter); + } + + if (0 == $this->displayOrder) { + $this->displayOrder = $coursesOtherLearningPaths->isEmpty() + ? 1 + : ( + 1 + max( + $coursesOtherLearningPaths->map( + function ($lp) { + return $lp->displayOrder; + } + )->toArray() + ) + ); + } + } + + /** + * If id is null, copies iid to id and writes again. + * Updates item properties. + * + * @throws OptimisticLockException + * + * @ORM\PostPersist + */ + public function postPersist() + { + if (is_null($this->id)) { + $this->id = $this->iid; + Database::getManager()->persist($this); + Database::getManager()->flush($this); + } + $courseInfo = api_get_course_info_by_id($this->course->getId()); + $userId = api_get_user_id(); + api_item_property_update( + $courseInfo, + TOOL_LEARNPATH, + $this->getId(), + 'LearnpathAdded', + $userId + ); + api_set_default_visibility( + $this->getId(), + TOOL_LEARNPATH, + 0, + $courseInfo, + $this->getSessionId(), + $userId + ); + } + + /** + * @return Course + */ + public function getCourse() + { + return $this->course; + } + + /** + * @param Course $course + * + * @return $this + */ + public function setCourse($course) + { + $this->course = $course; + $this->course->getLearningPaths()->add($this); + + return $this; } + /** + * @return Session + */ + /*public function getSession() + { + return $this->session; + }*/ + + /** + * @param Session $session + * + * @return $this + */ + /*public function setSession(Session $session) + { + $this->session = $session; + if (!is_null($session)) { + $this->session->getLearningPaths()->add($this); + } + + return $this; + }*/ + + /** + * @return CLpCategory + */ + /*public function getCategory() + { + return $this->category; + }*/ + + /** + * @param CLpCategory $category + * + * @return $this + */ + /*public function setCategory(CLpCategory $category) + { + $this->category = $category; + if (!is_null($category)) { + $this->category->getLearningPaths()->add($this); + } + + return $this; + }*/ + /** * Set lpType. * @@ -859,7 +1089,7 @@ public function getAutolaunch() /** * Set createdOn. * - * @param \DateTime $createdOn + * @param DateTime $createdOn * * @return CLp */ @@ -873,7 +1103,7 @@ public function setCreatedOn($createdOn) /** * Get createdOn. * - * @return \DateTime + * @return DateTime */ public function getCreatedOn() { @@ -883,7 +1113,7 @@ public function getCreatedOn() /** * Set modifiedOn. * - * @param \DateTime $modifiedOn + * @param DateTime $modifiedOn * * @return CLp */ @@ -897,7 +1127,7 @@ public function setModifiedOn($modifiedOn) /** * Get modifiedOn. * - * @return \DateTime + * @return DateTime */ public function getModifiedOn() { @@ -907,7 +1137,7 @@ public function getModifiedOn() /** * Set publicatedOn. * - * @param \DateTime $publicatedOn + * @param DateTime $publicatedOn * * @return CLp */ @@ -921,7 +1151,7 @@ public function setPublicatedOn($publicatedOn) /** * Get publicatedOn. * - * @return \DateTime + * @return DateTime */ public function getPublicatedOn() { @@ -931,7 +1161,7 @@ public function getPublicatedOn() /** * Set expiredOn. * - * @param \DateTime $expiredOn + * @param DateTime $expiredOn * * @return CLp */ @@ -945,7 +1175,7 @@ public function setExpiredOn($expiredOn) /** * Get expiredOn. * - * @return \DateTime + * @return DateTime */ public function getExpiredOn() { @@ -979,6 +1209,8 @@ public function getId() /** * Set cId. * + * @deprecated use setCourse wherever possible + * * @param int $cId * * @return CLp @@ -986,6 +1218,7 @@ public function getId() public function setCId($cId) { $this->cId = $cId; + $this->setCourse(api_get_course_entity($cId)); return $this; } @@ -1059,4 +1292,70 @@ public function getSubscribeUsers() { return $this->subscribeUsers; } + + /** + * @return ArrayCollection|CLpItem[] + */ + public function getItems() + { + return $this->items; + } + + /** + * Returns this learning path's final item. + * + * @return CLpItem|null the final item + */ + public function getFinalItem() + { + foreach ($this->items as $item) { + if ($item->getItemType() == TOOL_LP_FINAL_ITEM) { + return $item; + } + } + + return null; + } + + /** + * Returns this learning path's last item in first level that is not the final item. + * + * @return CLpItem|null the last item + */ + public function getLastItemInFirstLevel() + { + $last = null; + foreach ($this->items as $item) { + if (0 == $item->getParentItemId() && $item->getItemType() != TOOL_LP_FINAL_ITEM) { + if (is_null($last) || $last->getDisplayOrder() < $item->getDisplayOrder()) { + $last = $item; + } + } + } + + return $last; + } + + /** + * Updates this learning path's final item previous item id. + * Sets it to the last item in first level. + * + * @param bool $andFlush flush after persist + * + * @throws OptimisticLockException + */ + public function updateFinalItemsPreviousItemId($andFlush = true) + { + $finalItem = $this->getFinalItem(); + if (!is_null($finalItem)) { + $last = $this->getLastItemInFirstLevel(); + if (!is_null($last)) { + $finalItem->setPreviousItemId($last->getId()); + Database::getManager()->persist($finalItem); + if ($andFlush) { + Database::getManager()->flush($finalItem); + } + } + } + } } diff --git a/src/Chamilo/CourseBundle/Entity/CLpCategory.php b/src/Chamilo/CourseBundle/Entity/CLpCategory.php index 6b0d3c363da..a026451c68d 100644 --- a/src/Chamilo/CourseBundle/Entity/CLpCategory.php +++ b/src/Chamilo/CourseBundle/Entity/CLpCategory.php @@ -3,11 +3,15 @@ namespace Chamilo\CourseBundle\Entity; +use Chamilo\CoreBundle\Entity\Course; use Chamilo\UserBundle\Entity\User; +use Database; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Criteria; +use Doctrine\ORM\EntityRepository; use Doctrine\ORM\Mapping as ORM; use Gedmo\Mapping\Annotation as Gedmo; +use Gedmo\Sortable\Entity\Repository\SortableRepository; /** * CLpCategory. @@ -53,7 +57,12 @@ class CLpCategory /** * @var CLpCategoryUser[] * - * @ORM\OneToMany(targetEntity="Chamilo\CourseBundle\Entity\CLpCategoryUser", mappedBy="category", cascade={"persist", "remove"}, orphanRemoval=true) + * @ORM\OneToMany( + * targetEntity="Chamilo\CourseBundle\Entity\CLpCategoryUser", + * mappedBy="category", + * cascade={"persist", "remove"}, + * orphanRemoval=true + * ) */ protected $users; @@ -62,18 +71,69 @@ class CLpCategory */ protected $sessionId; + /** + * @var Course + * + * @ORM\ManyToOne(targetEntity="Chamilo\CoreBundle\Entity\Course", inversedBy="learningPathCategories") + * @ORM\JoinColumn(name="c_id", referencedColumnName="id") + */ + protected $course; + + /** + * @var CLp[]|ArrayCollection + * + * @ORM\OneToMany( + * targetEntity="Chamilo\CourseBundle\Entity\CLp", + * mappedBy="category", + * cascade={"persist", "remove"} + * ) + */ + /*protected $learningPaths;*/ + /** * CLpCategory constructor. */ public function __construct() { $this->users = new ArrayCollection(); + /*$this->learningPaths = new ArrayCollection();*/ $this->sessionId = 0; } + /** + * @return EntityRepository|SortableRepository + */ + public static function getRepository() + { + return Database::getManager()->getRepository('ChamiloCourseBundle:CLpCategory'); + } + + /** + * @return Course + */ + public function getCourse() + { + return $this->course; + } + + /** + * @param Course $course + * + * @return $this + */ + public function setCourse($course) + { + $this->course = $course; + $this->course->getLearningPathCategories()->add($this); + + return $this; + } + /** * Set cId. * + * @deprecated use setCourse wherever possible + * * @param int $cId * * @return CLpCategory @@ -81,6 +141,7 @@ public function __construct() public function setCId($cId) { $this->cId = $cId; + $this->setCourse(api_get_course_entity($cId)); return $this; } @@ -211,9 +272,11 @@ public function addUser(CLpCategoryUser $categoryUser) } /** + * @param CLpCategoryUser $categoryUser + * * @return bool */ - public function hasUser(CLpCategoryUser $categoryUser) + public function hasUser($categoryUser) { if ($this->getUsers()->count()) { $criteria = Criteria::create()->where( @@ -249,12 +312,22 @@ public function hasUserAdded($user) } /** + * @param CLpCategoryUser $user + * * @return $this */ - public function removeUsers(CLpCategoryUser $user) + public function removeUsers($user) { $this->users->removeElement($user); return $this; } + + /** + * @return CLp[]|ArrayCollection + */ + /*public function getLearningPaths() + { + return $this->learningPaths; + }*/ } diff --git a/src/Chamilo/CourseBundle/Entity/CLpItem.php b/src/Chamilo/CourseBundle/Entity/CLpItem.php index 9515cf04275..a23be25fa30 100644 --- a/src/Chamilo/CourseBundle/Entity/CLpItem.php +++ b/src/Chamilo/CourseBundle/Entity/CLpItem.php @@ -3,7 +3,12 @@ namespace Chamilo\CourseBundle\Entity; +use Chamilo\CoreBundle\Entity\Course; +use Database; +use Doctrine\ORM\EntityRepository; use Doctrine\ORM\Mapping as ORM; +use Doctrine\ORM\OptimisticLockException; +use Exception; /** * CLpItem. @@ -17,6 +22,7 @@ * } * ) * @ORM\Entity + * @ORM\HasLifecycleCallbacks() */ class CLpItem { @@ -197,12 +203,181 @@ class CLpItem */ protected $prerequisiteMaxScore; + /** + * @var CLp + * + * @ORM\ManyToOne( + * targetEntity="Chamilo\CourseBundle\Entity\CLp", + * inversedBy="items", + * cascade={"persist"} + * ) + * @ORM\JoinColumn( + * name="lp_id", + * referencedColumnName="iid", + * ) + */ + protected $learningPath; + + /** + * @var Course + * + * @ORM\ManyToOne(targetEntity="Chamilo\CoreBundle\Entity\Course", inversedBy="learningPathItems") + * @ORM\JoinColumn(name="c_id", referencedColumnName="id") + */ + protected $course; + /** * CLpItem constructor. */ public function __construct() { + $this->ref = 0; + $this->minScore = 0; $this->maxScore = 100.0; + $this->parentItemId = 0; + $this->previousItemId = 0; + $this->nextItemId = 0; + $this->displayOrder = 0; + $this->launchData = ''; + $this->path = ''; + } + + public function __toString() + { + return sprintf( + 'item %s (%s "%s") of %s', + $this->id, + $this->itemType, + $this->title, + $this->learningPath + ); + } + + /** + * @return EntityRepository + */ + public static function getRepository() + { + return Database::getManager()->getRepository('ChamiloCourseBundle:CLpItem'); + } + + /** + * If id is null, copies iid to id. + * If ref is empty or zero, copies iid to ref. + * if they still equal zero, computes displayOrder, previousItemId and nextItemId. + * If pointing to an enabled quiz, disables it and updates max score. + * + * @throws OptimisticLockException + * @throws Exception on quiz not found + * + * @ORM\PostPersist + */ + public function postPersist() + { + if (is_null($this->id)) { + $this->id = $this->iid; + } + if (is_null($this->ref) || empty($this->ref) || 0 == $this->ref) { + $this->ref = $this->iid; + } + if (empty($this->maxTimeAllowed)) { + $this->maxTimeAllowed = '0'; + } + + if (0 == $this->displayOrder) { + foreach ($this->getSiblings() as $sibling) { + if ($this->displayOrder < $sibling->displayOrder) { + $this->displayOrder = $sibling->displayOrder; + $this->previousItemId = 0; + } + } + if (0 == $this->displayOrder) { + $this->displayOrder = 1; + } + } else { + foreach ($this->getSiblings() as $sibling) { + if ($this->displayOrder === $sibling->displayOrder) { + $sibling->displayOrder++; + Database::getManager()->persist($sibling); + } + } + } + if (0 == $this->previousItemId) { + $previousSibling = $this->getPreviousSibling(); + if (!is_null($previousSibling)) { + $this->previousItemId = $previousSibling->iid; + $previousSibling->nextItemId = $this->iid; + Database::getManager()->persist($previousSibling); + } + } + if (0 == $this->nextItemId) { + $nextSibling = $this->getNextSibling(); + if (!is_null($nextSibling)) { + $this->nextItemId = $nextSibling->iid; + $nextSibling->previousItemId = $this->iid; + Database::getManager()->persist($nextSibling); + } + } + if ('quiz' === $this->itemType) { + /** @var CQuiz $quiz */ + $quiz = CQuiz::getRepository()->find($this->path); + if (is_null($quiz)) { + throw new Exception('no quiz has id '.$this->path); + } + $this->setMaxScore($quiz->getMaxScore()); + if ($quiz->getActive()) { + $quiz->setActive(false); + Database::getManager()->persist($quiz); + } + } + Database::getManager()->persist($this); + $this->learningPath->updateFinalItemsPreviousItemId(false); + Database::getManager()->flush(); + } + + /** + * Computes next sibling's previousItemId and previous sibling's nextItemId. + * + * @throws OptimisticLockException + * + * @ORM\PreRemove + */ + public function preRemove() + { + $previousSibling = $this->getPreviousSibling(); + $nextSibling = $this->getNextSibling(); + if (is_null($previousSibling)) { + if (!is_null($nextSibling)) { + $nextSibling->previousItemId = 0; + Database::getManager()->persist($nextSibling); + Database::getManager()->flush($nextSibling); + } + } else { + if (is_null($nextSibling)) { + $previousSibling->nextItemId = 0; + Database::getManager()->persist($previousSibling); + Database::getManager()->flush($previousSibling); + } else { + $previousSibling->nextItemId = $nextSibling->iid; + Database::getManager()->persist($previousSibling); + Database::getManager()->flush($previousSibling); + $nextSibling->previousItemId = $previousSibling->iid; + Database::getManager()->persist($nextSibling); + Database::getManager()->flush($nextSibling); + } + } + } + + /** + * Updates the final item's previous item id. + * + * @ORM\PostRemove + * + * @throws OptimisticLockException + */ + public function postRemove() + { + $this->learningPath->updateFinalItemsPreviousItemId(); } /** @@ -760,6 +935,8 @@ public function getId() /** * Set cId. * + * @deprecated use setCourse wherever possible + * * @param int $cId * * @return CLpItem @@ -767,6 +944,7 @@ public function getId() public function setCId($cId) { $this->cId = $cId; + $this->setCourse(api_get_course_entity($cId)); return $this; } @@ -780,4 +958,100 @@ public function getCId() { return $this->cId; } + + /** + * Sets learning path AND course (copying the learning path's). + * + * @param CLp $clp + * + * @return CLpItem + */ + public function setLearningPath($clp) + { + $this->learningPath = $clp; + $clp->getItems()->add($this); + $this->setCourse($clp->getCourse()); + + return $this; + } + + /** + * @return CLp + */ + public function getLearningPath() + { + return $this->learningPath; + } + + /** + * @param Course $course + * + * @return $this + */ + public function setCourse($course) + { + $this->course = $course; + $this->course->getLearningPathItems()->add($this); + + return $this; + } + + /** + * Retrieves the list of this instance's siblings, that is all the other children of this item's parent. + * + * @return static[] + */ + public function getSiblings() + { + $siblings = []; + foreach (self::getRepository()->findByParentItemId($this->parentItemId) as $candidate) { + if ($candidate !== $this) { + $siblings[] = $candidate; + } + } + + return $siblings; + } + + /** + * Returns the previous sibling according to displayOrders only (not looking at previousItemId). + * + * @return static|null + */ + public function getPreviousSibling() + { + $previousSibling = null; + foreach ($this->getSiblings() as $sibling) { + if ($sibling->displayOrder < $this->displayOrder) { + if (is_null($previousSibling)) { + $previousSibling = $sibling; + } elseif ($sibling->displayOrder > $previousSibling->displayOrder) { + $previousSibling = $sibling; + } + } + } + + return $previousSibling; + } + + /** + * Returns the next sibling according to displayOrders only (not looking at nextItemId). + * + * @return static|null + */ + public function getNextSibling() + { + $nextSibling = null; + foreach ($this->getSiblings() as $sibling) { + if ($sibling->displayOrder > $this->displayOrder) { + if (is_null($nextSibling)) { + $nextSibling = $sibling; + } elseif ($sibling->displayOrder < $nextSibling->displayOrder) { + $nextSibling = $sibling; + } + } + } + + return $nextSibling; + } } diff --git a/src/Chamilo/CourseBundle/Entity/CQuiz.php b/src/Chamilo/CourseBundle/Entity/CQuiz.php index 06d58c4c7ab..ce6019922d8 100644 --- a/src/Chamilo/CourseBundle/Entity/CQuiz.php +++ b/src/Chamilo/CourseBundle/Entity/CQuiz.php @@ -3,7 +3,13 @@ namespace Chamilo\CourseBundle\Entity; +use Chamilo\CoreBundle\Entity\Course; +use Database; +use DateTime; +use Doctrine\Common\Collections\ArrayCollection; +use Doctrine\ORM\EntityRepository; use Doctrine\ORM\Mapping as ORM; +use Doctrine\ORM\OptimisticLockException; /** * CQuiz. @@ -16,6 +22,7 @@ * } * ) * @ORM\Entity + * @ORM\HasLifecycleCallbacks */ class CQuiz { @@ -64,9 +71,9 @@ class CQuiz protected $sound; /** - * @var bool + * @var int * - * @ORM\Column(name="type", type="boolean", nullable=false) + * @ORM\Column(name="type", type="integer", nullable=false) */ protected $type; @@ -113,14 +120,14 @@ class CQuiz protected $maxAttempt; /** - * @var \DateTime + * @var DateTime * * @ORM\Column(name="start_time", type="datetime", nullable=true) */ protected $startTime; /** - * @var \DateTime + * @var DateTime * * @ORM\Column(name="end_time", type="datetime", nullable=true) */ @@ -156,7 +163,7 @@ class CQuiz /** * @var bool - * @ORm\Column(name="save_correct_answers", type="boolean", nullable=false) + * @ORM\Column(name="save_correct_answers", type="boolean", nullable=false) */ protected $saveCorrectAnswers; @@ -216,12 +223,83 @@ class CQuiz */ protected $exerciseCategoryId; + /** + * @var Course + * + * @ORM\ManyToOne(targetEntity="Chamilo\CoreBundle\Entity\Course", inversedBy="quizzes") + * @ORM\JoinColumn(name="c_id", referencedColumnName="id") + */ + protected $course; + + /** + * @var CQuizRelQuestion[]|ArrayCollection + * + * @ORM\OneToMany(targetEntity="Chamilo\CourseBundle\Entity\CQuizRelQuestion", mappedBy="quiz")) + */ + protected $relQuestions; + /** * CQuiz constructor. */ public function __construct() { $this->hideQuestionTitle = false; + $this->type = ONE_PER_PAGE; + $this->random = 0; + $this->randomAnswers = false; + $this->active = true; + $this->resultsDisabled = 0; + $this->maxAttempt = 1; + $this->feedbackType = 0; + $this->expiredTime = 0; + $this->propagateNeg = 0; + $this->saveCorrectAnswers = false; + $this->reviewAnswers = 0; + $this->randomByCategory = 0; + $this->displayCategoryName = 0; + } + + /** + * @return EntityRepository + */ + public static function getRepository() + { + return Database::getManager()->getRepository('ChamiloCourseBundle:CQuiz'); + } + + /** + * @return Course + */ + public function getCourse() + { + return $this->course; + } + + /** + * @param Course $course + * + * @return $this + */ + public function setCourse($course) + { + $this->course = $course; + $this->course->getQuizzes()->add($this); + + return $this; + } + + /** + * @ORM\PostPersist + * + * @throws OptimisticLockException + */ + public function postPersist() + { + if (is_null($this->id)) { + $this->id = $this->iid; + Database::getManager()->persist($this); + Database::getManager()->flush($this); + } } /** @@ -299,7 +377,7 @@ public function getSound() /** * Set type. * - * @param bool $type + * @param int $type * * @return CQuiz */ @@ -313,7 +391,7 @@ public function setType($type) /** * Get type. * - * @return bool + * @return int */ public function getType() { @@ -467,7 +545,7 @@ public function getMaxAttempt() /** * Set startTime. * - * @param \DateTime $startTime + * @param DateTime $startTime * * @return CQuiz */ @@ -481,7 +559,7 @@ public function setStartTime($startTime) /** * Get startTime. * - * @return \DateTime + * @return DateTime */ public function getStartTime() { @@ -491,7 +569,7 @@ public function getStartTime() /** * Set endTime. * - * @param \DateTime $endTime + * @param DateTime $endTime * * @return CQuiz */ @@ -505,7 +583,7 @@ public function setEndTime($endTime) /** * Get endTime. * - * @return \DateTime + * @return DateTime */ public function getEndTime() { @@ -775,6 +853,8 @@ public function getId() /** * Set cId. * + * @deprecated use setCourse wherever possible + * * @param int $cId * * @return CQuiz @@ -782,6 +862,7 @@ public function getId() public function setCId($cId) { $this->cId = $cId; + $this->setCourse(api_get_course_entity($cId)); return $this; } @@ -855,4 +936,17 @@ public function setIid($iid) return $this; } + + /** + * @return int sum of question's ponderation + */ + public function getMaxScore() + { + $maxScore = 0; + foreach ($this->relQuestions as $relQuestion) { + $maxScore += $relQuestion->getQuestion()->getPonderation(); + } + + return $maxScore; + } } diff --git a/src/Chamilo/CourseBundle/Entity/CQuizRelQuestion.php b/src/Chamilo/CourseBundle/Entity/CQuizRelQuestion.php index 49fec1427cf..2e74935eacc 100644 --- a/src/Chamilo/CourseBundle/Entity/CQuizRelQuestion.php +++ b/src/Chamilo/CourseBundle/Entity/CQuizRelQuestion.php @@ -57,6 +57,22 @@ class CQuizRelQuestion */ protected $exerciceId; + /** + * @var CQuiz + * + * @ORM\ManyToOne(targetEntity="CQuiz", inversedBy="relQuestions") + * @ORM\JoinColumn(name="exercice_id", referencedColumnName="iid") + */ + protected $quiz; + + /** + * @var CQuizQuestion + * + * @ORM\ManyToOne(targetEntity="Chamilo\CourseBundle\Entity\CQuizQuestion", inversedBy="relQuiz") + * @ORM\JoinColumn(name="question_id", referencedColumnName="iid") + */ + protected $question; + /** * Set questionOrder. * @@ -152,4 +168,14 @@ public function getExerciceId() { return $this->exerciceId; } + + public function getQuiz() + { + return $this->quiz; + } + + public function getQuestion() + { + return $this->question; + } } diff --git a/src/Chamilo/CourseBundle/Entity/CTool.php b/src/Chamilo/CourseBundle/Entity/CTool.php index 82b5a9886e1..600a99187a6 100644 --- a/src/Chamilo/CourseBundle/Entity/CTool.php +++ b/src/Chamilo/CourseBundle/Entity/CTool.php @@ -3,7 +3,10 @@ namespace Chamilo\CourseBundle\Entity; +use Chamilo\CoreBundle\Entity\Course; +use Database; use Doctrine\ORM\Mapping as ORM; +use Doctrine\ORM\OptimisticLockException; /** * CTool. @@ -16,6 +19,7 @@ * } * ) * @ORM\Entity + * @ORM\HasLifecycleCallbacks */ class CTool { @@ -126,6 +130,39 @@ class CTool */ protected $customIcon; + /** + * @var Course + * + * @ORM\ManyToOne(targetEntity="Chamilo\CoreBundle\Entity\Course", inversedBy="tools") + * @ORM\JoinColumn(name="c_id", referencedColumnName="id") + */ + protected $course; + + public function __construct() + { + $this->admin = 0; + $this->address = 'squaregrey.gif'; + $this->addedTool = false; + $this->target = '_self'; + $this->sessionId = 0; + } + + /** + * If id is null, copies iid to id and writes again. + * + * @ORM\PostPersist + * + * @throws OptimisticLockException + */ + public function postPersist() + { + if (is_null($this->id)) { // keep this test to avoid recursion + $this->id = $this->iid; + Database::getManager()->persist($this); + Database::getManager()->flush($this); + } + } + /** * @return int */ @@ -413,6 +450,8 @@ public function getId() /** * Set cId. * + * @deprecated use setCourse wherever possible + * * @param int $cId * * @return CTool @@ -420,6 +459,7 @@ public function getId() public function setCId($cId) { $this->cId = $cId; + $this->setCourse(api_get_course_entity($cId)); return $this; } @@ -473,4 +513,25 @@ public function setCustomIcon($customIcon) return $this; } + + /** + * @return Course + */ + public function getCourse() + { + return $this->course; + } + + /** + * @param Course $course + * + * @return $this + */ + public function setCourse($course) + { + $this->course = $course; + $this->course->getTools()->add($this); + + return $this; + } } diff --git a/src/Chamilo/UserBundle/Entity/User.php b/src/Chamilo/UserBundle/Entity/User.php index e3591a0ede3..17588c0a03d 100644 --- a/src/Chamilo/UserBundle/Entity/User.php +++ b/src/Chamilo/UserBundle/Entity/User.php @@ -3,11 +3,18 @@ namespace Chamilo\UserBundle\Entity; +use Chamilo\CoreBundle\Entity\CourseRelUser; use Chamilo\CoreBundle\Entity\ExtraFieldValues; +use Chamilo\CoreBundle\Entity\Session; use Chamilo\CoreBundle\Entity\SessionRelCourseRelUser; use Chamilo\CoreBundle\Entity\Skill; +use Chamilo\CoreBundle\Entity\UserCourseCategory; use Chamilo\CoreBundle\Entity\UsergroupRelUser; +use Chamilo\UserBundle\Repository\UserRepository; +use Database; use Doctrine\Common\Collections\ArrayCollection; +use Doctrine\Common\Collections\Criteria; +use Doctrine\ORM\EntityRepository; use Doctrine\ORM\Event\LifecycleEventArgs; use Doctrine\ORM\Mapping as ORM; use FOS\UserBundle\Model\GroupInterface; @@ -457,6 +464,14 @@ public function __toString() return $this->getUsername(); } + /** + * @return UserRepository|EntityRepository + */ + public static function getRepository() + { + return Database::getManager()->getRepository('ChamiloUserBundle:User'); + } + /** * Updates the id with the user_id. * @@ -2574,16 +2589,16 @@ public function getPictureLegacy() } /** - * Retreives this user's related sessions. + * Retrieves this user's related sessions. * * @param int $relationType \Chamilo\CoreBundle\Entity\SessionRelUser::relationTypeList key * - * @return \Chamilo\CoreBundle\Entity\Session[] + * @return Session[] */ public function getSessions($relationType) { $sessions = []; - foreach (\Database::getManager()->getRepository('ChamiloCoreBundle:SessionRelUser')->findBy([ + foreach (Database::getManager()->getRepository('ChamiloCoreBundle:SessionRelUser')->findBy([ 'user' => $this, ]) as $sessionRelUser) { if ($sessionRelUser->getRelationType() == $relationType) { @@ -2597,7 +2612,7 @@ public function getSessions($relationType) /** * Retreives this user's related student sessions. * - * @return \Chamilo\CoreBundle\Entity\Session[] + * @return Session[] */ public function getStudentSessions() { @@ -2607,7 +2622,7 @@ public function getStudentSessions() /** * Retreives this user's related DRH sessions. * - * @return \Chamilo\CoreBundle\Entity\Session[] + * @return Session[] */ public function getDRHSessions() { @@ -2619,7 +2634,7 @@ public function getDRHSessions() * * @param int $relationType \Chamilo\CoreBundle\Entity\SessionRelUser::relationTypeList key * - * @return \Chamilo\CoreBundle\Entity\Session[] + * @return Session[] */ public function getCurrentlyAccessibleSessions($relationType = 0) { @@ -2632,4 +2647,36 @@ public function getCurrentlyAccessibleSessions($relationType = 0) return $sessions; } + + /** + * Find the largest sort value in a given UserCourseCategory + * This method is used when we are moving a course to a different category + * and also when a user subscribes to courses (the new course is added at the end of the main category). + * + * Used to be implemented in global function \api_max_sort_value. + * Reimplemented using the ORM cache. + * + * @param UserCourseCategory|null $userCourseCategory the user_course_category + * + * @return int|mixed + */ + public function getMaxSortValue($userCourseCategory = null) + { + $categoryCourses = $this->courses->matching( + Criteria::create() + ->where(Criteria::expr()->neq('relationType', COURSE_RELATION_TYPE_RRHH)) + ->andWhere(Criteria::expr()->eq('userCourseCat', $userCourseCategory)) + ); + + return $categoryCourses->isEmpty() + ? 0 + : max( + $categoryCourses->map( + /** @var CourseRelUser $courseRelUser */ + function ($courseRelUser) { + return $courseRelUser->getSort(); + } + )->toArray() + ); + } }