diff --git a/public/main/admin/course_list.php b/public/main/admin/course_list.php index 0bbc7f86e5..996ae20940 100644 --- a/public/main/admin/course_list.php +++ b/public/main/admin/course_list.php @@ -155,7 +155,7 @@ function get_course_data($from, $number_of_items, $column, $direction, $dataFunc ); $actions[] = Display::url( Display::return_icon('statistics.png', get_lang('Reporting')), - $path.'tracking/courseLog.php?'.api_get_cidreq_params($courseCode) + $path.'tracking/courseLog.php?'.api_get_cidreq_params($courseId) ); $actions[] = Display::url( Display::return_icon('edit.png', get_lang('Edit')), @@ -163,7 +163,7 @@ function get_course_data($from, $number_of_items, $column, $direction, $dataFunc ); $actions[] = Display::url( Display::return_icon('backup.png', get_lang('Create a backup')), - $path.'coursecopy/create_backup.php?'.api_get_cidreq_params($courseCode) + $path.'coursecopy/create_backup.php?'.api_get_cidreq_params($courseId) ); $actions[] = Display::url( Display::return_icon('delete.png', get_lang('Delete')), diff --git a/public/main/admin/course_list_admin.php b/public/main/admin/course_list_admin.php index 56fd31004a..8a3c185c27 100644 --- a/public/main/admin/course_list_admin.php +++ b/public/main/admin/course_list_admin.php @@ -171,7 +171,7 @@ function get_course_data($from, $number_of_items, $column, $direction, $dataFunc );*/ $actions[] = Display::url( Display::return_icon('statistics.png', get_lang('Tracking')), - $path.'tracking/courseLog.php?'.api_get_cidreq_params($courseCode) + $path.'tracking/courseLog.php?'.api_get_cidreq_params($courseId) ); $actions[] = Display::url( Display::return_icon('edit.png', get_lang('Edit')), @@ -179,7 +179,7 @@ function get_course_data($from, $number_of_items, $column, $direction, $dataFunc ); $actions[] = Display::url( Display::return_icon('backup.png', get_lang('CreateBackup')), - $path.'coursecopy/create_backup.php?'.api_get_cidreq_params($courseCode) + $path.'coursecopy/create_backup.php?'.api_get_cidreq_params($courseId) ); $actions[] = Display::url( Display::return_icon('delete.png', get_lang('Delete')), diff --git a/public/main/forum/forumfunction.inc.php b/public/main/forum/forumfunction.inc.php index fca897185e..473115fb0b 100644 --- a/public/main/forum/forumfunction.inc.php +++ b/public/main/forum/forumfunction.inc.php @@ -5822,10 +5822,10 @@ function get_name_thread_by_id($thread_id) * * @return string */ -function get_all_post_from_user($user_id, $course_code) +function get_all_post_from_user($user_id, $courseId) { $j = 0; - $forums = get_forums('', $course_code); + $forums = get_forums($courseId); krsort($forums); $forum_results = ''; @@ -5846,7 +5846,7 @@ function get_all_post_from_user($user_id, $course_code) } if ($i <= 4) { $post_list = get_thread_user_post_limit( - $course_code, + $courseId, $thread['thread_id'], $user_id, 1 @@ -5880,7 +5880,7 @@ function get_all_post_from_user($user_id, $course_code) $forum_results .= '
'. Display::return_icon('forum.gif', get_lang('Forum')).' '.Security::remove_XSS($forum['forum_title'], STUDENT). '
- '. + '. get_lang('See forum').'
'; @@ -5905,19 +5905,18 @@ function get_all_post_from_user($user_id, $course_code) * * @return array */ -function get_thread_user_post_limit($course_code, $thread_id, $user_id, $limit = 10) +function get_thread_user_post_limit($courseId, $thread_id, $user_id, $limit = 10) { $table_posts = Database::get_course_table(TABLE_FORUM_POST); $table_users = Database::get_main_table(TABLE_MAIN_USER); - $course_info = api_get_course_info($course_code); - $course_id = $course_info['real_id']; + $courseId = (int) $courseId; $sql = "SELECT * FROM $table_posts posts - LEFT JOIN $table_users users + LEFT JOIN $table_users users ON posts.poster_id=users.user_id WHERE - posts.c_id = $course_id AND + posts.c_id = $courseId AND posts.thread_id='".Database::escape_string($thread_id)."' AND posts.poster_id='".Database::escape_string($user_id)."' ORDER BY posts.post_id DESC LIMIT $limit "; diff --git a/public/main/gradebook/lib/GradebookUtils.php b/public/main/gradebook/lib/GradebookUtils.php index c988ee14b2..277ef57a8e 100644 --- a/public/main/gradebook/lib/GradebookUtils.php +++ b/public/main/gradebook/lib/GradebookUtils.php @@ -257,7 +257,7 @@ class GradebookUtils } $courseParams = api_get_cidreq_params( - $cat->get_course_code(), + $cat->getCourseId(), $cat->get_session_id() ); diff --git a/public/main/inc/ajax/announcement.ajax.php b/public/main/inc/ajax/announcement.ajax.php index 19014b3d3e..65281c57c0 100644 --- a/public/main/inc/ajax/announcement.ajax.php +++ b/public/main/inc/ajax/announcement.ajax.php @@ -1,9 +1,7 @@ $requested_class, 'message' => $requested_message, 'view' => $requested_view, + 'fclass' => $requested_fa_class, ]; echo json_encode($response); } break; + case 'set_visibility_for_all': + require_once __DIR__.'/../global.inc.php'; + $course_id = api_get_course_int_id(); + $sessionId = api_get_session_id(); + $allowEditionInSession = api_get_configuration_value('allow_edit_tool_visibility_in_session'); + $response = []; + $tools_ids = json_decode($_GET['tools_ids']); + $em = Database::getManager(); + $repository = $em->getRepository('ChamiloCourseBundle:CTool'); + // Allow tool visibility in sessions. + if (api_is_allowed_to_edit(null, true)) { + if (is_array($tools_ids) && count($tools_ids) != 0) { + $total_tools = count($tools_ids); + for ($i = 0; $i < $total_tools; $i++) { + $tool_id = (int) $tools_ids[$i]; + + $criteria = [ + 'cId' => $course_id, + 'sessionId' => 0, + 'iid' => $tool_id, + ]; + /** @var CTool $tool */ + $tool = $repository->findOneBy($criteria); + $visibility = $tool->getVisibility(); + + if ($allowEditionInSession && !empty($sessionId)) { + $criteria = [ + 'cId' => $course_id, + 'sessionId' => $sessionId, + 'name' => $tool->getName(), + ]; + + /** @var CTool $tool */ + $toolInSession = $repository->findOneBy($criteria); + if ($toolInSession) { + // Use the session + $tool = $toolInSession; + $visibility = $toolInSession->getVisibility(); + } else { + // Creates new row in c_tool + $toolInSession = clone $tool; + $toolInSession->setIid(0); + $toolInSession->setId(0); + $toolInSession->setVisibility(0); + $toolInSession->setSessionId($session_id); + $em->persist($toolInSession); + $em->flush(); + // Update id with iid + $toolInSession->setId($toolInSession->getIid()); + $em->persist($toolInSession); + $em->flush(); + // $tool will be updated later + $tool = $toolInSession; + } + } + + $toolImage = $tool->getImage(); + $customIcon = $tool->getCustomIcon(); + + if (api_get_setting('homepage_view') != 'activity_big') { + $toolImage = Display::return_icon( + $toolImage, + null, + null, + null, + null, + true + ); + $inactiveImage = str_replace('.gif', '_na.gif', $toolImage); + } else { + // Display::return_icon() also checks in the app/Resources/public/css/themes/{theme}/icons folder + $toolImage = (substr($toolImage, 0, strpos($toolImage, '.'))).'.png'; + $toolImage = Display::return_icon( + $toolImage, + get_lang(ucfirst($tool->getName())), + null, + ICON_SIZE_BIG, + null, + true + ); + $inactiveImage = str_replace('.png', '_na.png', $toolImage); + } + + if (isset($customIcon) && !empty($customIcon)) { + $toolImage = CourseHome::getCustomWebIconPath().$customIcon; + $inactiveImage = CourseHome::getCustomWebIconPath().CourseHome::getDisableIcon($customIcon); + } + + $requested_image = $visibility == 0 ? $toolImage : $inactiveImage; + $requested_class = $visibility == 0 ? '' : 'text-muted'; + $requested_message = $visibility == 0 ? 'is_active' : 'is_inactive'; + $requested_view = $visibility == 0 ? 'visible.png' : 'invisible.png'; + $requestedVisible = $visibility == 0 ? 1 : 0; + $requested_view = $visibility == 0 ? 'visible.png' : 'invisible.png'; + $requested_fa_class = $visibility == 0 ? 'fa fa-eye '.$requested_class : 'fa fa-eye-slash '.$requested_class; + $requestedVisible = $visibility == 0 ? 1 : 0; + + // HIDE AND REACTIVATE TOOL + if ($tool_id == strval(intval($tool_id))) { + $tool->setVisibility($requestedVisible); + $em->persist($tool); + $em->flush(); + + // Also hide the tool in all sessions + if ($allowEditionInSession && empty($sessionId)) { + $criteria = [ + 'cId' => $course_id, + 'name' => $tool->getName(), + ]; + + /** @var CTool $toolItem */ + $tools = $repository->findBy($criteria); + foreach ($tools as $toolItem) { + $toolSessionId = $toolItem->getSessionId(); + if (!empty($toolSessionId)) { + $toolItem->setVisibility($requestedVisible); + $em->persist($toolItem); + } + } + $em->flush(); + } + } + $response[] = [ + 'image' => $requested_image, + 'tclass' => $requested_class, + 'message' => $requested_message, + 'view' => $requested_view, + 'fclass' => $requested_fa_class, + 'id' => $tool_id, + ]; + } + } + } + echo json_encode($response); + break; case 'show_course_information': require_once __DIR__.'/../global.inc.php'; diff --git a/public/main/inc/ajax/lp.ajax.php b/public/main/inc/ajax/lp.ajax.php index a1ad001cba..4c77753401 100644 --- a/public/main/inc/ajax/lp.ajax.php +++ b/public/main/inc/ajax/lp.ajax.php @@ -91,60 +91,22 @@ switch ($action) { break; case 'update_lp_item_order': if (api_is_allowed_to_edit(null, true)) { + // $new_order gets a value like "647|0^648|0^649|0^" $new_order = $_POST['new_order']; $sections = explode('^', $new_order); + $sections = array_filter($sections); // We have to update parent_item_id, previous_item_id, next_item_id, display_order in the database - $itemList = new LpItemOrderList(); + $orderList = []; + foreach ($sections as $items) { - if (!empty($items)) { - list($id, $parent_id) = explode('|', $items); - $item = new LpOrderItem($id, $parent_id); - $itemList->add($item); - } - } + list($id, $parentId) = explode('|', $items); - $parents = $itemList->getListOfParents(); - foreach ($parents as $parentId) { - $sameParentLpItemList = $itemList->getItemWithSameParent($parentId); - $previous_item_id = 0; - for ($i = 0; $i < count($sameParentLpItemList->list); $i++) { - $item_id = $sameParentLpItemList->list[$i]->id; - // display_order - $display_order = $i + 1; - $itemList->setParametersForId($item_id, $display_order, 'display_order'); - // previous_item_id - $itemList->setParametersForId($item_id, $previous_item_id, 'previous_item_id'); - $previous_item_id = $item_id; - // next_item_id - $next_item_id = 0; - if ($i < count($sameParentLpItemList->list) - 1) { - $next_item_id = $sameParentLpItemList->list[$i + 1]->id; - } - $itemList->setParametersForId($item_id, $next_item_id, 'next_item_id'); - } + $orderList[$id] = $parentId; } - $table = Database::get_course_table(TABLE_LP_ITEM); - - foreach ($itemList->list as $item) { - $params = []; - $params['display_order'] = $item->display_order; - $params['previous_item_id'] = $item->previous_item_id; - $params['next_item_id'] = $item->next_item_id; - $params['parent_item_id'] = $item->parent_item_id; + learnpath::sortItemByOrderList($orderList); - Database::update( - $table, - $params, - [ - 'iid = ? AND c_id = ? ' => [ - intval($item->id), - $courseId, - ], - ] - ); - } - echo Display::return_message(get_lang('Saved.'), 'confirm'); + echo Display::return_message(get_lang('Saved'), 'confirm'); } break; case 'record_audio': @@ -164,11 +126,11 @@ switch ($action) { foreach (['video', 'audio'] as $type) { if (isset($_FILES["${type}-blob"])) { $fileName = $_POST["${type}-filename"]; - //$file = $_FILES["${type}-blob"]["tmp_name"]; $file = $_FILES["${type}-blob"]; + $title = $_POST['audio-title']; $fileInfo = pathinfo($fileName); - $file['name'] = 'rec_'.date('Y-m-d_His').'_'.uniqid().'.'.$fileInfo['extension']; + $file['name'] = $title.'.'.$fileInfo['extension']; $file['file'] = $file; $result = DocumentManager::upload_document( @@ -199,17 +161,8 @@ switch ($action) { break; case 'get_forum_thread': - // FORUM - LP connection disabled - if (empty($lpId) || empty($lpItemId)) { - echo json_encode([ - 'error' => true, - ]); - - break; - } - - $lpId = isset($_GET['lp']) ? (int) $_GET['lp'] : 0; - $lpItemId = isset($_GET['lp_item']) ? (int) $_GET['lp_item'] : 0; + $lpId = isset($_GET['lp']) ? intval($_GET['lp']) : 0; + $lpItemId = isset($_GET['lp_item']) ? intval($_GET['lp_item']) : 0; $sessionId = api_get_session_id(); if (empty($lpId) || empty($lpItemId)) { @@ -360,101 +313,3 @@ switch ($action) { default: echo ''; } -exit; - -/** - * Class LpItemOrderList - * Classes to create a special data structure to manipulate LP Items - * used only in this file. - * - * @todo move in a file - * @todo use PSR - */ -class LpItemOrderList -{ - public $list = []; - - public function __construct() - { - $this->list = []; - } - - /** - * @param array $list - */ - public function add($list) - { - $this->list[] = $list; - } - - /** - * @param int $parentId - * - * @return LpItemOrderList - */ - public function getItemWithSameParent($parentId) - { - $list = new LpItemOrderList(); - for ($i = 0; $i < count($this->list); $i++) { - if ($this->list[$i]->parent_item_id == $parentId) { - $list->add($this->list[$i]); - } - } - - return $list; - } - - /** - * @return array - */ - public function getListOfParents() - { - $result = []; - foreach ($this->list as $item) { - if (!in_array($item->parent_item_id, $result)) { - $result[] = $item->parent_item_id; - } - } - - return $result; - } - - /** - * @param int $id - * @param int $value - * @param string $parameter - */ - public function setParametersForId($id, $value, $parameter) - { - for ($i = 0; $i < count($this->list); $i++) { - if ($this->list[$i]->id == $id) { - $this->list[$i]->$parameter = $value; - break; - } - } - } -} - -/** - * Class LpOrderItem. - */ -class LpOrderItem -{ - public $id = 0; - public $parent_item_id = 0; - public $previous_item_id = 0; - public $next_item_id = 0; - public $display_order = 0; - - /** - * LpOrderItem constructor. - * - * @param int $id - * @param int $parentId - */ - public function __construct($id = 0, $parentId = 0) - { - $this->id = $id; - $this->parent_item_id = $parentId; - } -} diff --git a/public/main/inc/ajax/model.ajax.php b/public/main/inc/ajax/model.ajax.php index 3a25bd53d1..397b45cbd6 100644 --- a/public/main/inc/ajax/model.ajax.php +++ b/public/main/inc/ajax/model.ajax.php @@ -454,9 +454,7 @@ switch ($action) { $sessionIdList = array_column($sessionList, 'id'); $courseCodeList = []; foreach ($sessionList as $session) { - $courses = SessionManager::get_course_list_by_session_id( - $session['id'] - ); + $courses = SessionManager::get_course_list_by_session_id($session['id']); $courseCodeList = array_merge( $courseCodeList, array_column($courses, 'code') @@ -515,7 +513,8 @@ switch ($action) { null, $courseCodeList, $userIdList, - $sessionIdList + $sessionIdList, + ['where' => $whereCondition, 'extra' => $extra_fields] ); } else { $count = CourseManager::get_count_user_list_from_course_code( @@ -523,7 +522,8 @@ switch ($action) { ['ruc'], $courseCodeList, $userIdList, - $sessionIdList + $sessionIdList, + ['where' => $whereCondition, 'extra' => $extra_fields] ); } break; diff --git a/public/main/inc/ajax/record_audio_rtc.ajax.php b/public/main/inc/ajax/record_audio_rtc.ajax.php index cb22d4d7b3..ce3c07d8be 100644 --- a/public/main/inc/ajax/record_audio_rtc.ajax.php +++ b/public/main/inc/ajax/record_audio_rtc.ajax.php @@ -56,7 +56,13 @@ switch ($type) { 0, 'overwrite', false, - in_array($tool, ['document', 'exercise']) + in_array($tool, ['document', 'exercise']), + 'file', + true, + api_get_user_id(), + $courseInfo, + api_get_session_id(), + api_get_group_id() ); $error = empty($uploadedDocument) || !is_array($uploadedDocument); diff --git a/public/main/inc/ajax/sequence.ajax.php b/public/main/inc/ajax/sequence.ajax.php index cb7ad10eab..0f4ebf4f7e 100644 --- a/public/main/inc/ajax/sequence.ajax.php +++ b/public/main/inc/ajax/sequence.ajax.php @@ -30,7 +30,6 @@ $sequenceResourceRepository = $em->getRepository('ChamiloCoreBundle:SequenceReso switch ($action) { case 'graph': api_block_anonymous_users(); - api_protect_admin_script(); /** @var Sequence $sequence */ $sequence = $sequenceRepository->find($sequenceId); @@ -46,10 +45,6 @@ switch ($action) { $graphImage = ''; try { $graphImage = $graphviz->createImageSrc($graph); - - //echo $graphviz->createScript($graph); - //$graphviz->display($graph); - echo Display::img( $graphImage, get_lang('GraphDependencyTree'), @@ -434,7 +429,6 @@ switch ($action) { $sequenceList = $sequenceResourceRepository->checkRequirementsForUser($sequences, $type, $userId); $allowSubscription = $sequenceResourceRepository->checkSequenceAreCompleted($sequenceList); - $courseController = new CoursesController(); $view = new Template(null, false, false, false, false, false); $view->assign('sequences', $sequenceList); $view->assign('sequence_type', $type); @@ -443,7 +437,7 @@ switch ($action) { if ($allowSubscription) { $view->assign( 'subscribe_button', - $courseController->getRegisteredInSessionButton( + CoursesAndSessionsCatalog::getRegisteredInSessionButton( $id, $resourceName, false diff --git a/public/main/inc/ajax/session.ajax.php b/public/main/inc/ajax/session.ajax.php index 3bbd09cb9c..54ab82041b 100644 --- a/public/main/inc/ajax/session.ajax.php +++ b/public/main/inc/ajax/session.ajax.php @@ -267,9 +267,7 @@ switch ($action) { if ('get_basic_course_documents_list' === $action) { $courseInfo = api_get_course_info_by_id($course->getId()); - $exists = DocumentManager::folderExists('/basic-course-documents', $courseInfo, $session->getId(), 0); - if (!$exists) { $courseDir = $courseInfo['directory'].'/document'; $sysCoursePath = api_get_path(SYS_COURSE_PATH); @@ -303,6 +301,7 @@ switch ($action) { false, $session->getId() ); + $documentAndFolders = array_filter( $documentAndFolders, function (array $documentData) { diff --git a/public/main/inc/ajax/social.ajax.php b/public/main/inc/ajax/social.ajax.php index 90ffa2da1a..e927ee239d 100644 --- a/public/main/inc/ajax/social.ajax.php +++ b/public/main/inc/ajax/social.ajax.php @@ -142,7 +142,7 @@ switch ($action) { if (api_is_user_of_course($course_id, api_get_user_id())) { //------Forum messages - $forum_result = get_all_post_from_user($user_id, $course_code); + $forum_result = get_all_post_from_user($user_id, $course_id); $all_result_data = 0; if ('' != $forum_result) { echo '
'; diff --git a/public/main/inc/ajax/user_manager.ajax.php b/public/main/inc/ajax/user_manager.ajax.php index b6ee4a1e4f..dd15d880eb 100644 --- a/public/main/inc/ajax/user_manager.ajax.php +++ b/public/main/inc/ajax/user_manager.ajax.php @@ -227,18 +227,6 @@ switch ($action) { false, $additionalParameters ); - - /*$result = api_mail_html( - $recipientName, - $user_info['mail'], - $subject, - $body, - $sender_name, - $emailAdmin, - null, - null, - $additionalParameters - );*/ Event::addEvent(LOG_USER_ENABLE, LOG_USER_ID, $user_id); } else { Event::addEvent(LOG_USER_DISABLE, LOG_USER_ID, $user_id); @@ -253,6 +241,7 @@ switch ($action) { api_block_anonymous_users(false); $status = isset($_REQUEST['status']) ? (int) $_REQUEST['status'] : DRH; + $active = isset($_REQUEST['active']) ? (int) $_REQUEST['active'] : null; $criteria = new Criteria(); $criteria @@ -267,6 +256,9 @@ switch ($action) { Criteria::expr()->eq('status', $status) ); + if (null !== $active) { + $criteria->andWhere(Criteria::expr()->eq('active', $active)); + } $users = UserManager::getRepository()->matching($criteria); if (!$users->count()) { diff --git a/public/main/inc/lib/CoursesAndSessionsCatalog.class.php b/public/main/inc/lib/CoursesAndSessionsCatalog.class.php index ac9b23e5bd..fa3bee9b38 100644 --- a/public/main/inc/lib/CoursesAndSessionsCatalog.class.php +++ b/public/main/inc/lib/CoursesAndSessionsCatalog.class.php @@ -6,7 +6,6 @@ use Doctrine\ORM\Query\Expr\Join; /** * @todo change class name - * Class CoursesAndSessionsCatalog */ class CoursesAndSessionsCatalog { @@ -259,10 +258,11 @@ class CoursesAndSessionsCatalog $urlCondition = ' (access_url_id = '.$urlId.' OR access_url_id = 1) '; } - $sql = "SELECT COUNT(*) FROM $tbl_course course + $sql = "SELECT COUNT(*) + FROM $tbl_course course INNER JOIN $tbl_url_rel_course as url_rel_course ON (url_rel_course.c_id = course.id) - WHERE access_url_id = '.$urlId.' "; + WHERE access_url_id = $urlId"; $result = Database::query($sql); list($num_records) = Database::fetch_row($result); @@ -278,7 +278,8 @@ class CoursesAndSessionsCatalog ORDER BY RAND() LIMIT 0, $randomValue"; } else { - $sql = "SELECT id, id as real_id FROM $tbl_course course + $sql = "SELECT id, id as real_id + FROM $tbl_course course WHERE RAND()*$num_records< $randomValue $avoidCoursesCondition @@ -319,7 +320,7 @@ class CoursesAndSessionsCatalog $conditionCode .= " category_code='$categoryCode' "; } - if (empty($categoryCode) || $categoryCode == 'ALL') { + if (empty($categoryCode) || $categoryCode === 'ALL') { $sql = "SELECT *, id as real_id FROM $tbl_course course WHERE @@ -343,7 +344,8 @@ class CoursesAndSessionsCatalog $urlCondition = ' access_url_id = '.$urlId.' '; if ($categoryCode !== 'ALL') { - $sql = "SELECT *, course.id real_id FROM $tbl_course as course + $sql = "SELECT *, course.id real_id + FROM $tbl_course as course INNER JOIN $tbl_url_rel_course as url_rel_course ON (url_rel_course.c_id = course.id) WHERE @@ -445,7 +447,8 @@ class CoursesAndSessionsCatalog $categoryFilter = ' AND category_code = "'.$categoryCode.'" '; } - $sql = "SELECT DISTINCT course.*, $injectExtraFields + //$sql = "SELECT DISTINCT course.*, $injectExtraFields + $sql = "SELECT DISTINCT(course.id) FROM $courseTable course $sqlInjectJoins WHERE ( @@ -472,7 +475,7 @@ class CoursesAndSessionsCatalog $urlCondition = ' (access_url_id = '.$urlId.' OR access_url_id = 1) AND '; } - $sql = "SELECT DISTINCT course.*, $injectExtraFields + $sql = "SELECT DISTINCT(course.id) FROM $courseTable as course INNER JOIN $tbl_url_rel_course as url_rel_course ON (url_rel_course.c_id = course.id) @@ -498,9 +501,15 @@ class CoursesAndSessionsCatalog $result = Database::query($sql); $courses = []; while ($row = Database::fetch_array($result)) { - $row['registration_code'] = !empty($row['registration_code']); + $courseId = $row['id']; + $courseInfo = api_get_course_info_by_id($courseId); + if (empty($courseInfo)) { + continue; + } + $courseCode = $courseInfo['code']; + $countUsers = CourseManager::get_user_list_from_course_code( - $row['code'], + $courseCode, 0, null, null, @@ -508,29 +517,18 @@ class CoursesAndSessionsCatalog true ); $connectionsLastMonth = Tracking::get_course_connections_count( - $row['id'], + $courseId, 0, api_get_utc_datetime(time() - (30 * 86400)) ); - $ranking = CourseManager::get_course_ranking($row['id'], 0); - $courses[] = [ - 'real_id' => $row['id'], - 'point_info' => $ranking, - 'code' => $row['code'], - 'directory' => $row['directory'], - 'visual_code' => $row['visual_code'], - 'title' => $row['title'], - 'tutor' => $row['tutor_name'], - 'subscribe' => $row['subscribe'], - 'unsubscribe' => $row['unsubscribe'], - 'registration_code' => $row['registration_code'], - 'creation_date' => $row['creation_date'], - 'visibility' => $row['visibility'], - 'count_users' => $countUsers, - 'category_code' => $row['category_code'], - 'count_connections' => $connectionsLastMonth, - ]; + $courseInfo['point_info'] = CourseManager::get_course_ranking($courseId, 0); + $courseInfo['tutor'] = $courseInfo['tutor_name']; + $courseInfo['registration_code'] = !empty($courseInfo['registration_code']); + $courseInfo['count_users'] = $countUsers; + $courseInfo['count_connections'] = $connectionsLastMonth; + + $courses[] = $courseInfo; } return $courses; @@ -714,36 +712,6 @@ class CoursesAndSessionsCatalog public static function browseSessions($date = null, $limit = [], $returnQueryBuilder = false, $getCount = false) { $urlId = api_get_current_access_url_id(); - - /*$dql = "SELECT $select - FROM ChamiloCoreBundle:Session s - WHERE EXISTS - ( - SELECT url.sessionId FROM ChamiloCoreBundle:AccessUrlRelSession url - WHERE url.sessionId = s.id AND url.accessUrlId = $urlId - ) AND - s.nbrCourses > 0 - "; - if (!is_null($date)) { - $date = Database::escape_string($date); - $dql .= " - AND ( - (s.accessEndDate IS NULL) - OR - ( - s.accessStartDate IS NOT NULL AND - s.accessEndDate IS NOT NULL AND - s.accessStartDate <= '$date' AND s.accessEndDate >= '$date') - OR - ( - s.accessStartDate IS NULL AND - s.accessEndDate IS NOT NULL AND - s.accessEndDate >= '$date' - ) - ) - "; - }*/ - $em = Database::getManager(); $qb = $em->createQueryBuilder(); $qb2 = $em->createQueryBuilder(); diff --git a/public/main/inc/lib/agenda.lib.php b/public/main/inc/lib/agenda.lib.php index 67c052c75d..91daa83efa 100644 --- a/public/main/inc/lib/agenda.lib.php +++ b/public/main/inc/lib/agenda.lib.php @@ -1075,21 +1075,7 @@ class Agenda break; case 'course': $courseId = api_get_course_int_id(); - $sessionId = api_get_session_id(); - $isAllowToEdit = api_is_allowed_to_edit(null, true); - - if (false == $isAllowToEdit && !empty($sessionId)) { - $allowDhrToEdit = api_get_configuration_value('allow_agenda_edit_for_hrm'); - if ($allowDhrToEdit) { - $isHrm = SessionManager::isUserSubscribedAsHRM( - $sessionId, - api_get_user_id() - ); - if ($isHrm) { - $isAllowToEdit = true; - } - } - } + $isAllowToEdit = $this->getIsAllowedToEdit(); if (!empty($courseId) && $isAllowToEdit) { // Delete @@ -3146,6 +3132,13 @@ class Agenda Display::return_icon('1day.png', get_lang('Sessions plan calendar'), [], ICON_SIZE_MEDIUM), $codePath."calendar/planification.php" ); + + if (api_is_student_boss() || api_is_platform_admin()) { + $actionsLeft .= Display::url( + Display::return_icon('calendar-user.png', get_lang('MyStudentsSchedule'), [], ICON_SIZE_MEDIUM), + $codePath.'mySpace/calendar_plan.php' + ); + } } if (api_is_platform_admin() || diff --git a/public/main/inc/lib/api.lib.php b/public/main/inc/lib/api.lib.php index 1bd7be88ef..7c69e40c1b 100644 --- a/public/main/inc/lib/api.lib.php +++ b/public/main/inc/lib/api.lib.php @@ -2121,19 +2121,19 @@ function api_get_anonymous_id() } /** - * @param string $courseCode + * @param int $courseId * @param int $sessionId * @param int $groupId * * @return string */ -function api_get_cidreq_params($courseCode, $sessionId = 0, $groupId = 0) +function api_get_cidreq_params($courseId, $sessionId = 0, $groupId = 0) { - $courseCode = !empty($courseCode) ? htmlspecialchars($courseCode) : ''; + $courseId = !empty($courseId) ? (int) $courseId :0; $sessionId = !empty($sessionId) ? (int) $sessionId : 0; $groupId = !empty($groupId) ? (int) $groupId : 0; - $url = 'cid='.$courseCode; + $url = 'cid='.$courseId; $url .= '&sid='.$sessionId; $url .= '&gid='.$groupId; @@ -3401,6 +3401,7 @@ function api_display_tool_title($title_element) if (is_string($title_element)) { $tit = $title_element; unset($title_element); + $title_element = []; $title_element['mainTitle'] = $tit; } echo '

'; diff --git a/public/main/inc/lib/array.lib.php b/public/main/inc/lib/array.lib.php index 6782a5d45a..9796f2e830 100644 --- a/public/main/inc/lib/array.lib.php +++ b/public/main/inc/lib/array.lib.php @@ -52,11 +52,11 @@ function msort($array, $id = 'id', $order = 'desc') $index = 0; foreach ($array as $item) { if ('desc' == $order) { - if ($item[$id] < $array[$lowest_id][$id]) { + if (strip_tags($item[$id]) < strip_tags($array[$lowest_id][$id])) { $lowest_id = $index; } } else { - if (isset($item[$id]) && $item[$id] > $array[$lowest_id][$id]) { + if (isset($item[$id]) && strip_tags($item[$id]) > strip_tags($array[$lowest_id][$id])) { $lowest_id = $index; } } diff --git a/public/main/inc/lib/attendance.lib.php b/public/main/inc/lib/attendance.lib.php index 99aa9a8399..580f93ab4b 100644 --- a/public/main/inc/lib/attendance.lib.php +++ b/public/main/inc/lib/attendance.lib.php @@ -279,6 +279,31 @@ class Attendance return $attendances; } + /** + * Get the attendances by id to display on the current page. + * + * @param int $attendanceId + * + * @return array attendance data + */ + public function get_attendance_by_id($attendanceId) + { + $tbl_attendance = Database::get_course_table(TABLE_ATTENDANCE); + $attendanceId = (int) $attendanceId; + $course_id = api_get_course_int_id(); + $attendance_data = []; + $sql = "SELECT * FROM $tbl_attendance + WHERE c_id = $course_id AND id = '$attendanceId'"; + $res = Database::query($sql); + if (Database::num_rows($res) > 0) { + while ($row = Database::fetch_array($res)) { + $attendance_data = $row; + } + } + + return $attendance_data; + } + /** * Add attendances sheet inside table. This is the *list of* dates, not * a specific date in itself. @@ -1196,15 +1221,24 @@ class Attendance public function get_users_attendance_sheet( $attendanceId, $user_id = 0, - $groupId = 0 + $groupId = 0, + $course_id = 0, + DateTime $startDate = null, + DateTime $endDate = null ) { + //Get actual course or by course_id + $course_id = (0 == $course_id) ? api_get_course_int_id() : (int) $course_id; $tbl_attendance_sheet = Database::get_course_table(TABLE_ATTENDANCE_SHEET); $tbl_attendance_calendar = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR); $attendance_calendar = $this->get_attendance_calendar( $attendanceId, 'all', null, - $groupId + $groupId, + true, + $course_id, + $startDate, + $endDate ); $calendar_ids = []; // get all dates from calendar by current attendance @@ -1212,7 +1246,16 @@ class Attendance $calendar_ids[] = $cal['id']; } - $course_id = api_get_course_int_id(); + $whereDate = ''; + if (!empty($startDate)) { + $whereDate .= " AND cal.date_time >= '".$startDate->format('Y-m-d H:i:s')."'"; + } + if (!empty($endDate)) { + $whereDate .= " AND cal.date_time <= '".$endDate->format('Y-m-d H:i:s')."'"; + } + + // moved at start of this function + // $course_id = api_get_course_int_id(); $data = []; if (empty($user_id)) { @@ -1248,16 +1291,13 @@ class Attendance att.c_id = $course_id AND cal.c_id = $course_id AND att.user_id = '$user_id' AND - att.attendance_calendar_id IN (".implode(',', $calendar_ids).') - ORDER BY date_time'; + att.attendance_calendar_id IN (".implode(',', $calendar_ids).") + $whereDate + ORDER BY date_time"; $res = Database::query($sql); if (Database::num_rows($res) > 0) { while ($row = Database::fetch_array($res)) { - $row['date_time'] = api_convert_and_format_date( - $row['date_time'], - null, - date_default_timezone_get() - ); + $row['date_time'] = api_convert_and_format_date($row['date_time'], null, date_default_timezone_get()); $data[$user_id][] = $row; } } @@ -1413,6 +1453,9 @@ class Attendance * @param int $calendar_id * @param int $groupId * @param bool $showAll = false show group calendar items or not + * @param int $course_id + * @param DateTime $startDate Filter calendar with a start date + * @param DateTime $endDate Filter calendar with a end date * * @return array attendance calendar data */ @@ -1421,16 +1464,27 @@ class Attendance $type = 'all', $calendar_id = null, $groupId = 0, - $showAll = false + $showAll = false, + $course_id = 0, + DateTime $startDate = null, + DateTime $endDate = null ) { $tbl_attendance_calendar = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR); $tbl_acrg = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR_REL_GROUP); $attendanceId = (int) $attendanceId; - $course_id = api_get_course_int_id(); - + $course_id = (0 == $course_id) ? api_get_course_int_id() : (int) $course_id; + $whereDate = ''; + if (!empty($startDate)) { + $whereDate .= " AND c.date_time >= '".$startDate->format('Y-m-d H:i:s')."'"; + } + if (!empty($endDate)) { + $whereDate .= " AND c.date_time <= '".$endDate->format('Y-m-d H:i:s')."'"; + } if ($showAll) { $sql = "SELECT * FROM $tbl_attendance_calendar c - WHERE c_id = $course_id AND attendance_id = '$attendanceId'"; + WHERE c_id = $course_id + AND attendance_id = '$attendanceId' + $whereDate"; } else { $sql = "SELECT * FROM $tbl_attendance_calendar c WHERE @@ -1440,6 +1494,7 @@ class Attendance SELECT calendar_id FROM $tbl_acrg WHERE c_id = $course_id AND group_id != 0 AND group_id IS NOT NULL ) + $whereDate "; } diff --git a/public/main/inc/lib/auth.lib.php b/public/main/inc/lib/auth.lib.php index d2d27dbcd4..8cb251287c 100644 --- a/public/main/inc/lib/auth.lib.php +++ b/public/main/inc/lib/auth.lib.php @@ -18,76 +18,12 @@ class Auth { } - /** - * retrieves all the courses that the user has already subscribed to. - * - * @param int $user_id - * - * @return array an array containing all the information of the courses of the given user - */ - public function get_courses_of_user($user_id) - { - $TABLECOURS = Database::get_main_table(TABLE_MAIN_COURSE); - $TABLECOURSUSER = Database::get_main_table(TABLE_MAIN_COURSE_USER); - $avoidCoursesCondition = CoursesAndSessionsCatalog::getAvoidCourseCondition(); - $visibilityCondition = CourseManager::getCourseVisibilitySQLCondition('course', true); - $tblCourseCategory = Database::get_main_table(TABLE_MAIN_CATEGORY); - - // Secondly we select the courses that are in a category (user_course_cat<>0) and - // sort these according to the sort of the category - $user_id = (int) $user_id; - $sql = "SELECT - course.code k, - course.visual_code vc, - course.subscribe subscr, - course.unsubscribe unsubscr, - course.title i, - course.tutor_name t, - category.code cat, - course.directory dir, - course_rel_user.status status, - course_rel_user.sort sort, - course_rel_user.user_course_cat user_course_cat - FROM $TABLECOURS as course - LEFT JOIN $tblCourseCategory category - ON course.category_id = category.id, - $TABLECOURSUSER course_rel_user - WHERE - course.id = course_rel_user.c_id AND - course_rel_user.relation_type <> ".COURSE_RELATION_TYPE_RRHH." AND - course_rel_user.user_id = '".$user_id."' - $avoidCoursesCondition - $visibilityCondition - ORDER BY course_rel_user.sort ASC"; - - $result = Database::query($sql); - $courses = []; - while ($row = Database::fetch_array($result)) { - //we only need the database name of the course - $courses[] = [ - 'code' => $row['k'], - 'visual_code' => $row['vc'], - 'title' => $row['i'], - 'directory' => $row['dir'], - 'status' => $row['status'], - 'tutor' => $row['t'], - 'subscribe' => $row['subscr'], - 'category' => $row['cat'], - 'unsubscribe' => $row['unsubscr'], - 'sort' => $row['sort'], - 'user_course_category' => $row['user_course_cat'], - ]; - } - - return $courses; - } - /** * This function get all the courses in the particular user category. * * @return array */ - public function get_courses_in_category() + public function getCoursesInCategory() { $user_id = api_get_user_id(); @@ -169,7 +105,7 @@ class Auth $table = Database::get_main_table(TABLE_MAIN_COURSE_USER); $current_user_id = api_get_user_id(); - $all_user_courses = $this->get_courses_of_user($current_user_id); + $all_user_courses = CourseManager::getCoursesByUserCourseCategory($current_user_id); // we need only the courses of the category we are moving in $user_courses = []; @@ -238,7 +174,7 @@ class Auth public function move_category($direction, $category2move) { $userId = api_get_user_id(); - $userCategories = CourseManager::get_user_course_categories(api_get_user_id()); + $userCategories = CourseManager::get_user_course_categories($userId); $categories = array_values($userCategories); $previous = null; @@ -290,7 +226,6 @@ class Auth */ public function store_edit_course_category($title, $category_id) { - // protect data $title = Database::escape_string($title); $category_id = (int) $category_id; $result = false; @@ -355,9 +290,8 @@ class Auth id= $categoryId AND user_id= $userId"; $resultQuery = Database::query($sql); - $result = Database::fetch_array($resultQuery, 'ASSOC'); - return $result; + return Database::fetch_array($resultQuery, 'ASSOC'); } /** @@ -412,7 +346,6 @@ class Auth // protect data $current_user_id = api_get_user_id(); $category_title = Database::escape_string($category_title); - $result = false; // step 1: we determine the max value of the user defined course categories $sql = "SELECT sort FROM $table @@ -430,15 +363,19 @@ class Auth title='".$category_title."' ORDER BY sort DESC"; $rs = Database::query($sql); - if (0 == Database::num_rows($rs)) { + + $result = false; + if (Database::num_rows($rs) == 0) { $sql = "INSERT INTO $table (user_id, title,sort) - VALUES ('".$current_user_id."', '".api_htmlentities($category_title, ENT_QUOTES, api_get_system_encoding())."', '".$nextsort."')"; + VALUES ('".$current_user_id."', '".api_htmlentities( + $category_title, + ENT_QUOTES, + api_get_system_encoding() + )."', '".$nextsort."')"; $resultQuery = Database::query($sql); if (Database::affected_rows($resultQuery)) { $result = true; } - } else { - $result = false; } return $result; diff --git a/public/main/inc/lib/certificate.lib.php b/public/main/inc/lib/certificate.lib.php index 89b43b2ae3..580efd4b9a 100644 --- a/public/main/inc/lib/certificate.lib.php +++ b/public/main/inc/lib/certificate.lib.php @@ -1,6 +1,8 @@ setEncoding('UTF-8'); + $qrCode->setSize(120); + $qrCode->setMargin(5); $qrCode->setWriterByName('png'); + $qrCode->setErrorCorrectionLevel(ErrorCorrectionLevel::MEDIUM()); + $qrCode->setForegroundColor(['r' => 0, 'g' => 0, 'b' => 0, 'a' => 0]); + $qrCode->setBackgroundColor(['r' => 255, 'g' => 255, 'b' => 255, 'a' => 0]); + $qrCode->setValidateResult(false); $qrCode->writeFile($path); - //L low, M - Medium, L large error correction - //return QrCode::png($text, $path, 'M', 2, 2); - - return file_exists($path); + return true; } return false; diff --git a/public/main/inc/lib/course.lib.php b/public/main/inc/lib/course.lib.php index 59169ecf90..598a8f9861 100644 --- a/public/main/inc/lib/course.lib.php +++ b/public/main/inc/lib/course.lib.php @@ -2357,13 +2357,13 @@ class CourseManager $tbl_session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER); $sql = "SELECT DISTINCT - u.user_id, + u.id as user_id, u.lastname, u.firstname, u.username FROM $tbl_user u INNER JOIN $tbl_session_course_user scu - ON (u.user_id = scu.user_id) + ON (u.id = scu.user_id) WHERE scu.session_id = $session_id AND scu.c_id = $courseId AND @@ -2821,8 +2821,10 @@ class CourseManager } if (api_strcasecmp($course_title_precedent, $course_title) < 0) { $course_found = true; - $course_sort = $courses['sort']; - if (0 == $counter) { + if (!empty($courses['sort'])) { + $course_sort = $courses['sort']; + } + if ($counter == 0) { $sql = "UPDATE $TABLECOURSUSER SET sort = sort+1 WHERE @@ -2970,39 +2972,52 @@ class CourseManager $courseTable = Database::get_main_table(TABLE_MAIN_COURSE); $tbl_course_field = Database::get_main_table(TABLE_EXTRA_FIELD); $tbl_course_field_value = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES); - - //we filter the courses from the URL - $join_access_url = $where_access_url = ''; - if (api_get_multiple_access_url()) { - $access_url_id = api_get_current_access_url_id(); - if (-1 != $access_url_id) { $tbl_url_course = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE); - $join_access_url = "LEFT JOIN $tbl_url_course url_rel_course - ON url_rel_course.c_id = tcfv.item_id "; - $where_access_url = " AND access_url_id = $access_url_id "; - } - } $extraFieldType = EntityExtraField::COURSE_FIELD_TYPE; + $courseList = []; // get course list auto-register - $sql = "SELECT DISTINCT(c.id) - FROM $tbl_course_field_value tcfv - INNER JOIN $tbl_course_field tcf - ON tcfv.field_id = tcf.id $join_access_url - INNER JOIN $courseTable c - ON (c.id = tcfv.item_id) - WHERE - tcf.extra_field_type = $extraFieldType AND - tcf.variable = 'special_course' AND - tcfv.value = 1 $where_access_url"; + $sql = "SELECT id FROM $tbl_course_field + WHERE extra_field_type = $extraFieldType AND + variable = 'special_course'"; $result = Database::query($sql); $courseList = []; if (Database::num_rows($result) > 0) { - while ($row = Database::fetch_array($result)) { - $courseList[] = $row['id']; + $row = Database::fetch_assoc($result); + // Get list of special courses (appear to all) + // Note: The value is better indexed as string, so + // using '1' instead of integer is more efficient + $sql = "SELECT DISTINCT(item_id) as cid + FROM $tbl_course_field_value + WHERE field_id = ".$row['id']." AND value = '1'"; + $result = Database::query($sql); + while ($row = Database::fetch_assoc($result)) { + $courseList[] = $row['cid']; + } + if (count($courseList) < 1) { + return $courseList; + } + if (api_get_multiple_access_url()) { + //we filter the courses by the active URL + $coursesSelect = ''; + if (count($courseList) == 1) { + $coursesSelect = $courseList[0]; + } else { + $coursesSelect = implode(',', $courseList); + } + $access_url_id = api_get_current_access_url_id(); + if ($access_url_id != -1) { + $sql = "SELECT c_id FROM $tbl_url_course + WHERE access_url_id = $access_url_id + AND c_id IN ($coursesSelect)"; + $result = Database::query($sql); + while ($row = Database::fetch_assoc($result)) { + $courseList[] = $row['c_id']; + } + } } } @@ -3305,14 +3320,6 @@ class CourseManager */ public static function update_attributes($id, $attributes) { - $courseCategory = CourseCategory::getCategory($attributes['category_code']); - - unset($attributes['category_code']); - - if (!empty($courseCategory)) { - $attributes['category_id'] = $courseCategory['id']; - } - $id = (int) $id; $table = Database::get_main_table(TABLE_MAIN_COURSE); $sql = "UPDATE $table SET "; @@ -3403,7 +3410,7 @@ class CourseManager /** * Gets extra field value data and formatted values of a course - * for extra fields listed in configuration.php in My_course_course_extrafields_to_be_presented + * for extra fields listed in configuration.php in my_course_course_extrafields_to_be_presented * (array of variables as value of key 'fields'). * * @param $courseId int The numeric identifier of the course @@ -3413,7 +3420,7 @@ class CourseManager public static function getExtraFieldsToBePresented($courseId) { $extraFields = []; - $fields = api_get_configuration_sub_value('My_course_course_extrafields_to_be_presented/fields'); + $fields = api_get_configuration_sub_value('my_course_course_extrafields_to_be_presented/fields'); if (!empty($fields) && is_array($fields)) { $extraFieldManager = new ExtraField('course'); $dataAndFormattedValues = $extraFieldManager->getDataAndFormattedValues($courseId); @@ -3909,7 +3916,7 @@ class CourseManager 'not_category' => [], ]; $collapsable = api_get_configuration_value('allow_user_course_category_collapsable'); - $stok = Security::get_token(); + $stok = Security::get_existing_token(); while ($row = Database::fetch_array($result)) { // We simply display the title of the category. $courseInCategory = self::returnCoursesCategories( @@ -4302,11 +4309,7 @@ class CourseManager return ''; } - $userInCourseStatus = self::getUserInCourseStatus( - $user_id, - $course_info['real_id'] - ); - + $userInCourseStatus = self::getUserInCourseStatus($user_id, $course_info['real_id']); $course_info['status'] = empty($session_id) ? $userInCourseStatus : STUDENT; $course_info['id_session'] = $session_id; @@ -6067,7 +6070,7 @@ class CourseManager public static function getCourseUsers($filterByActive = null) { // This would return only the users from real courses: - $userList = self::get_user_list_from_course_code( + return self::get_user_list_from_course_code( api_get_course_id(), api_get_session_id(), null, @@ -6081,8 +6084,6 @@ class CourseManager [], $filterByActive ); - - return $userList; } /** @@ -6115,7 +6116,7 @@ class CourseManager * * @return HTML_QuickForm_element */ - public static function addUserGroupMultiSelect(&$form, $alreadySelected) + public static function addUserGroupMultiSelect(&$form, $alreadySelected, $addShortCut = false) { $userList = self::getCourseUsers(true); $groupList = self::getCourseGroups(); @@ -6131,13 +6132,50 @@ class CourseManager $result[$content['value']] = $content['content']; } - return $form->addElement( + $multiple = $form->addElement( 'advmultiselect', 'users', get_lang('Users'), $result, - ['select_all_checkbox' => true] + ['select_all_checkbox' => true, 'id' => 'users'] ); + + $sessionId = api_get_session_id(); + if ($addShortCut && empty($sessionId)) { + $addStudents = []; + foreach ($userList as $user) { + if ($user['status_rel'] == STUDENT) { + $addStudents[] = $user['user_id']; + } + } + if (!empty($addStudents)) { + $form->addHtml( + '' + ); + + $form->addLabel( + '', + Display::url(get_lang('AddStudent'), '#', ['id' => 'add_students', 'class' => 'btn btn-primary']) + ); + } + } + + return $multiple; } /** @@ -6955,13 +6993,24 @@ class CourseManager private static function checkCreateCourseAccessUrlParam($_configuration, $accessUrlId, $param, $msgLabel) { if (isset($_configuration[$accessUrlId][$param]) && $_configuration[$accessUrlId][$param] > 0) { + $num = null; + switch ($param) { + case 'hosting_limit_courses': $num = self::count_courses($accessUrlId); - if ($num >= $_configuration[$accessUrlId][$param]) { + break; + case 'hosting_limit_active_courses': + $num = self::countActiveCourses($accessUrlId); + break; + } + + if ($num && $num >= $_configuration[$accessUrlId][$param]) { api_warn_hosting_contact($param); Display::addFlash( Display::return_message($msgLabel) ); + + return true; } } diff --git a/public/main/inc/lib/course_category.lib.php b/public/main/inc/lib/course_category.lib.php index 91bccad862..a6037adc49 100644 --- a/public/main/inc/lib/course_category.lib.php +++ b/public/main/inc/lib/course_category.lib.php @@ -158,9 +158,8 @@ class CourseCategory ORDER BY t1.parent_id, t1.tree_pos"; $result = Database::query($sql); - $categories = Database::store_result($result, 'ASSOC'); - return $categories; + return Database::store_result($result, 'ASSOC'); } /** @@ -469,9 +468,8 @@ class CourseCategory foreach ($parents as $category) { $categories[] = $category['code']; } - $categoriesInString = implode(' > ', $categories).' > '; - return $categoriesInString; + return implode(' > ', $categories).' > '; } return null; @@ -710,6 +708,11 @@ class CourseCategory $conditions = " INNER JOIN $table a ON (c.id = a.course_category_id)"; $whereCondition = " AND a.access_url_id = ".api_get_current_access_url_id(); + $allowBaseCategories = api_get_configuration_value('allow_base_course_category'); + if ($allowBaseCategories) { + $whereCondition = " AND (a.access_url_id = ".api_get_current_access_url_id()." OR a.access_url_id = 1) "; + } + $keyword = Database::escape_string($keyword); $sql = "SELECT c.*, c.name as text diff --git a/public/main/inc/lib/course_request.lib.php b/public/main/inc/lib/course_request.lib.php index 33d409fdaf..cdd7728445 100644 --- a/public/main/inc/lib/course_request.lib.php +++ b/public/main/inc/lib/course_request.lib.php @@ -611,11 +611,20 @@ class CourseRequestManager $email_body .= get_lang('Email', null, $email_language).': '.api_get_setting('emailAdministrator', null, $email_language)."\n"; $email_body .= "\n".get_lang('CourseRequestLegalNote', null, $email_language)."\n"; - $sender_name = api_get_person_name(api_get_setting('administratorName'), api_get_setting('administratorSurname'), null, PERSON_NAME_EMAIL_ADDRESS); + $sender_name = api_get_person_name( + api_get_setting('administratorName'), + api_get_setting('administratorSurname'), + null, + PERSON_NAME_EMAIL_ADDRESS + ); $sender_email = api_get_setting('emailAdministrator'); - $recipient_name = api_get_person_name($user_info['firstname'], $user_info['lastname'], null, PERSON_NAME_EMAIL_ADDRESS); + $recipient_name = api_get_person_name( + $user_info['firstname'], + $user_info['lastname'], + null, + PERSON_NAME_EMAIL_ADDRESS + ); $recipient_email = $user_info['mail']; - $extra_headers = 'Bcc: '.$sender_email; $additionalParameters = [ 'smsType' => SmsPlugin::COURSE_OPENING_REQUEST_CODE_REJECTED, @@ -697,9 +706,13 @@ class CourseRequestManager PERSON_NAME_EMAIL_ADDRESS ); $sender_email = api_get_setting('emailAdministrator'); - $recipient_name = api_get_person_name($user_info['firstname'], $user_info['lastname'], null, PERSON_NAME_EMAIL_ADDRESS); + $recipient_name = api_get_person_name( + $user_info['firstname'], + $user_info['lastname'], + null, + PERSON_NAME_EMAIL_ADDRESS + ); $recipient_email = $user_info['mail']; - $extra_headers = 'Bcc: '.$sender_email; $additionalParameters = [ 'smsType' => SmsPlugin::COURSE_OPENING_REQUEST_CODE, diff --git a/public/main/inc/lib/events.lib.php b/public/main/inc/lib/events.lib.php index da75fe3f8f..7deaf75522 100644 --- a/public/main/inc/lib/events.lib.php +++ b/public/main/inc/lib/events.lib.php @@ -508,6 +508,7 @@ class Event $position = Database::escape_string($position); $now = api_get_utc_datetime(); $course_id = (int) $course_id; + $recording = api_get_configuration_value('quiz_answer_extra_recording') == true; // check user_id or get from context if (empty($user_id)) { @@ -613,13 +614,14 @@ class Event error_log("Insert attempt with id #$attempt_id"); } - if (defined('ENABLED_LIVE_EXERCISE_TRACKING')) { + if ($recording) { if ($debug) { error_log("Saving e attempt recording "); } $attempt_recording = [ 'exe_id' => $attempt_id, 'question_id' => $question_id, + 'answer' => $answer, 'marks' => $score, 'insert_date' => $now, 'author' => '', @@ -640,10 +642,11 @@ class Event ] ); - if (defined('ENABLED_LIVE_EXERCISE_TRACKING')) { + if ($recording) { $attempt_recording = [ 'exe_id' => $exe_id, 'question_id' => $question_id, + 'answer' => $answer, 'marks' => $score, 'insert_date' => $now, 'author' => '', @@ -2042,6 +2045,7 @@ class Event * @param int $sessionId The session in which to add the time (if any) * @param string $virtualTime The amount of time to be added, * in a hh:mm:ss format. If int, we consider it is expressed in hours. + * @param int $workId Student publication id result * * @return true on successful insertion, false otherwise */ @@ -2049,8 +2053,13 @@ class Event $courseId, $userId, $sessionId, - $virtualTime = '' + $virtualTime, + $workId ) { + if (empty($virtualTime)) { + return false; + } + $courseId = (int) $courseId; $userId = (int) $userId; $sessionId = (int) $sessionId; @@ -2062,6 +2071,7 @@ class Event false ); + $ip = api_get_real_ip(); $params = [ 'login_course_date' => $loginDate, 'logout_course_date' => $logoutDate, @@ -2069,11 +2079,50 @@ class Event 'user_id' => $userId, 'counter' => 0, 'c_id' => $courseId, - 'user_ip' => api_get_real_ip(), + 'user_ip' => $ip, ]; $courseTrackingTable = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS); Database::insert($courseTrackingTable, $params); + // Time should also be added to the track_e_login table so as to + // affect total time on the platform + $params = [ + 'login_user_id' => $userId, + 'login_date' => $loginDate, + 'user_ip' => $ip, + 'logout_date' => $logoutDate, + ]; + $platformTrackingTable = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN); + Database::insert($platformTrackingTable, $params); + + if (Tracking::minimumTimeAvailable($sessionId, $courseId)) { + $workId = (int) $workId; + $uniqueId = time(); + $logInfo = [ + 'c_id' => $courseId, + 'session_id' => $sessionId, + 'tool' => TOOL_STUDENTPUBLICATION, + 'date_reg' => $loginDate, + 'action' => 'add_work_start_'.$workId, + 'action_details' => $virtualTime, + 'user_id' => $userId, + 'current_id' => $uniqueId, + ]; + self::registerLog($logInfo); + + $logInfo = [ + 'c_id' => $courseId, + 'session_id' => $sessionId, + 'tool' => TOOL_STUDENTPUBLICATION, + 'date_reg' => $logoutDate, + 'action' => 'add_work_end_'.$workId, + 'action_details' => $virtualTime, + 'user_id' => $userId, + 'current_id' => $uniqueId, + ]; + self::registerLog($logInfo); + } + return true; } @@ -2100,18 +2149,24 @@ class Event $courseId, $userId, $sessionId = 0, - $virtualTime = '' + $virtualTime, + $workId ) { if (empty($virtualTime)) { return false; } + + $originalVirtualTime = $virtualTime; + $courseTrackingTable = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS); + $platformTrackingTable = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN); $courseId = (int) $courseId; $userId = (int) $userId; $sessionId = (int) $sessionId; // Change $virtualTime format from hh:mm:ss to hhmmss which is the // format returned by SQL for a subtraction of two datetime values // @todo make sure this is portable between DBMSes + // @todo make sure this is portable between DBMSes if (preg_match('/:/', $virtualTime)) { list($h, $m, $s) = preg_split('/:/', $virtualTime); $virtualTime = $h * 3600 + $m * 60 + $s; @@ -2140,9 +2195,55 @@ class Event $courseAccessId = $row[0]; $sql = "DELETE FROM $courseTrackingTable WHERE course_access_id = $courseAccessId"; + Database::query($sql); + } + $sql = "SELECT login_id + FROM $platformTrackingTable + WHERE + login_user_id = $userId AND + (UNIX_TIMESTAMP(logout_date) - UNIX_TIMESTAMP(login_date)) = '$virtualTime' + ORDER BY login_date DESC LIMIT 0,1"; + $result = Database::query($sql); + if (Database::num_rows($result) > 0) { + + $row = Database::fetch_row($result); + $loginAccessId = $row[0]; + $sql = "DELETE FROM $platformTrackingTable + WHERE login_id = $loginAccessId"; + Database::query($sql); + } + + if (Tracking::minimumTimeAvailable($sessionId, $courseId)) { + $workId = (int) $workId; + $sql = "SELECT id FROM track_e_access_complete + WHERE + tool = '".TOOL_STUDENTPUBLICATION."' AND + c_id = $courseId AND + session_id = $sessionId AND + user_id = $userId AND + action_details = '$originalVirtualTime' AND + action = 'add_work_start_$workId' "; $result = Database::query($sql); + $result = Database::fetch_array($result); + if ($result) { + $sql = 'DELETE FROM track_e_access_complete WHERE id = '.$result['id']; + Database::query($sql); + } - return $result; + $sql = "SELECT id FROM track_e_access_complete + WHERE + tool = '".TOOL_STUDENTPUBLICATION."' AND + c_id = $courseId AND + session_id = $sessionId AND + user_id = $userId AND + action_details = '$originalVirtualTime' AND + action = 'add_work_end_$workId' "; + $result = Database::query($sql); + $result = Database::fetch_array($result); + if ($result) { + $sql = 'DELETE FROM track_e_access_complete WHERE id = '.$result['id']; + Database::query($sql); + } } return false; @@ -2161,6 +2262,14 @@ class Event $sessionId = api_get_session_id(); $courseId = api_get_course_int_id(); + if (isset($logInfo['c_id']) && !empty($logInfo['c_id'])) { + $courseId = $logInfo['c_id']; + } + + if (isset($logInfo['session_id']) && !empty($logInfo['session_id'])) { + $sessionId = $logInfo['session_id']; + } + if (!Tracking::minimumTimeAvailable($sessionId, $courseId)) { return false; } @@ -2169,10 +2278,10 @@ class Event return false; } - $loginAs = true === (int) Session::read('login_as'); + $loginAs = (int) Session::read('login_as') === true; - $logInfo['user_id'] = api_get_user_id(); - $logInfo['date_reg'] = api_get_utc_datetime(); + $logInfo['user_id'] = isset($logInfo['user_id']) ? $logInfo['user_id'] : api_get_user_id(); + $logInfo['date_reg'] = isset($logInfo['date_reg']) ? $logInfo['date_reg'] : api_get_utc_datetime(); $logInfo['tool'] = !empty($logInfo['tool']) ? $logInfo['tool'] : ''; $logInfo['tool_id'] = !empty($logInfo['tool_id']) ? (int) $logInfo['tool_id'] : 0; $logInfo['tool_id_detail'] = !empty($logInfo['tool_id_detail']) ? (int) $logInfo['tool_id_detail'] : 0; @@ -2186,7 +2295,7 @@ class Event $logInfo['login_as'] = $loginAs; $logInfo['info'] = !empty($logInfo['info']) ? $logInfo['info'] : ''; $logInfo['url'] = $_SERVER['REQUEST_URI']; - $logInfo['current_id'] = Session::read('last_id', 0); + $logInfo['current_id'] = isset($logInfo['current_id']) ? $logInfo['current_id'] : Session::read('last_id', 0); $id = Database::insert('track_e_access_complete', $logInfo); if ($id && empty($logInfo['current_id'])) { diff --git a/public/main/inc/lib/formvalidator/Element/DateRangePicker.php b/public/main/inc/lib/formvalidator/Element/DateRangePicker.php index cb9cdb5a15..35262cfb3e 100644 --- a/public/main/inc/lib/formvalidator/Element/DateRangePicker.php +++ b/public/main/inc/lib/formvalidator/Element/DateRangePicker.php @@ -1,4 +1,5 @@ getAttribute('timePicker') && false === strpos($this->getAttribute('format'), 'HH:mm')) { $pattern = 'yyyy-MM-dd'; @@ -182,12 +182,17 @@ class DateRangePicker extends HTML_QuickForm_text $timePicker = 'false'; } + $timeIncrement = 30; + if (api_get_configuration_value('timepicker_increment')) { + $timeIncrement = api_get_configuration_value('timepicker_increment'); + } + // timeFormat: 'hh:mm' $js .= "'); - } - - /** - * Show an icon at the left side of an input - * @return string - */ - public function getIconToHtml() - { - $icon = $this->getIcon(); - $isButton = $this->getButton(); - - if (empty($icon)) { - return ''; - } - $element = ''; - - if ($isButton) { - $element = ''; - } - - return '
- ' . $element . ' -
'; + ' + ); } /** @@ -591,17 +567,18 @@ class HTML_QuickForm_select extends HTML_QuickForm_element switch ($layout) { case FormValidator::LAYOUT_INLINE: return ' -