From 62480b44131cdcf8e6fd941b082c3a21c3b0b4d0 Mon Sep 17 00:00:00 2001 From: Julio Montoya Date: Tue, 7 Aug 2018 14:59:47 +0200 Subject: [PATCH] Minor - partial merge from 1.11.x --- main/inc/lib/AnnouncementEmail.php | 34 +- main/inc/lib/AnnouncementManager.php | 15 +- main/inc/lib/CourseChatUtils.php | 91 +- .../lib/CoursesAndSessionsCatalog.class.php | 6 +- main/inc/lib/ScheduledAnnouncement.php | 2 +- main/inc/lib/TicketManager.php | 37 +- main/inc/lib/agenda.lib.php | 471 +++++----- main/inc/lib/api.lib.php | 229 +++-- main/inc/lib/banner.lib.php | 30 +- main/inc/lib/certificate.lib.php | 28 +- main/inc/lib/course.lib.php | 117 ++- main/inc/lib/course_description.lib.php | 2 +- main/inc/lib/course_home.lib.php | 83 +- main/inc/lib/database.constants.inc.php | 3 + main/inc/lib/diagnoser.lib.php | 7 +- main/inc/lib/document.lib.php | 86 +- main/inc/lib/events.lib.php | 166 ++-- main/inc/lib/exercise.lib.php | 668 +++++++++++--- main/inc/lib/exercise_show_functions.lib.php | 91 +- main/inc/lib/extra_field.lib.php | 43 +- main/inc/lib/extra_field_option.lib.php | 2 +- main/inc/lib/extra_field_value.lib.php | 55 +- main/inc/lib/fixlinks.js | 4 +- main/inc/lib/groupmanager.lib.php | 7 +- main/inc/lib/legal.lib.php | 44 +- main/inc/lib/link.lib.php | 6 +- main/inc/lib/message.lib.php | 181 +++- main/inc/lib/myspace.lib.php | 85 +- main/inc/lib/notebook.lib.php | 5 +- main/inc/lib/pdf.lib.php | 24 +- main/inc/lib/plugin.class.php | 46 +- main/inc/lib/security.lib.php | 3 +- main/inc/lib/sessionmanager.lib.php | 190 ++-- main/inc/lib/skill.lib.php | 81 +- main/inc/lib/social.lib.php | 18 +- main/inc/lib/sortable_table.class.php | 6 +- main/inc/lib/template.lib.php | 4 + main/inc/lib/tracking.lib.php | 214 +++-- main/inc/lib/usergroup.lib.php | 257 +++++- main/inc/lib/usermanager.lib.php | 850 ++++++++++++------ main/inc/lib/userportal.lib.php | 55 +- 41 files changed, 3058 insertions(+), 1288 deletions(-) diff --git a/main/inc/lib/AnnouncementEmail.php b/main/inc/lib/AnnouncementEmail.php index ddc94d6dff..7560e1dfcf 100644 --- a/main/inc/lib/AnnouncementEmail.php +++ b/main/inc/lib/AnnouncementEmail.php @@ -298,18 +298,30 @@ class AnnouncementEmail } foreach ($users as $user) { - if (!empty($this->logger)) { - $this->logger->addInfo('Announcement: #'.$this->announcement('id').'. Send email to user: #'.$user['user_id']); - } $message = $this->message($user['user_id']); - MessageManager::send_message_simple( - $user['user_id'], - $subject, - $message, - $senderId, - $sendToDrhUsers, - true - ); + $wasSent = MessageManager::messageWasAlreadySent($senderId, $user['user_id'], $subject, $message); + if ($wasSent === false) { + if (!empty($this->logger)) { + $this->logger->addInfo( + 'Announcement: #'.$this->announcement('id').'. Send email to user: #'.$user['user_id'] + ); + } + MessageManager::send_message_simple( + $user['user_id'], + $subject, + $message, + $senderId, + $sendToDrhUsers, + true + ); + } else { + if (!empty($this->logger)) { + $this->logger->addInfo( + 'Message "'.$subject.'" was already sent. Announcement: #'.$this->announcement('id').'. + User: #'.$user['user_id'] + ); + } + } if (($counter % $batchSize) === 0) { $em->flush(); diff --git a/main/inc/lib/AnnouncementManager.php b/main/inc/lib/AnnouncementManager.php index 7b5cca4fe3..3185efe8e3 100755 --- a/main/inc/lib/AnnouncementManager.php +++ b/main/inc/lib/AnnouncementManager.php @@ -439,8 +439,6 @@ class AnnouncementManager } //$toUser = $itemProperty->getToUser(); - //$toUserId = !empty($toUser) ? $toUser->getId() : 0; - // The user id is always the current one. $toUserId = api_get_user_id(); $content = self::parseContent( $toUserId, @@ -456,7 +454,8 @@ class AnnouncementManager $html .= Display::dateToStringAgoAndLongDate($lastEdit); $html .= ""; - if (api_is_allowed_to_edit(false, true)) { + $allow = !api_get_configuration_value('hide_announcement_sent_to_users_info'); + if (api_is_allowed_to_edit(false, true) && $allow) { $sent_to = self::sent_to('announcement', $id); $sent_to_form = self::sent_to_form($sent_to); $html .= Display::tag( @@ -807,7 +806,7 @@ class AnnouncementManager $courseId = api_get_course_int_id(); $tbl_item_property = Database::get_course_table(TABLE_ITEM_PROPERTY); $table = Database::get_course_table(TABLE_ANNOUNCEMENT); - $id = intval($id); + $id = (int) $id; $params = [ 'title' => $title, @@ -825,7 +824,7 @@ class AnnouncementManager $id_attach = 0; if ($row_attach) { - $id_attach = intval($row_attach['id']); + $id_attach = (int) $row_attach['id']; } if (!empty($file)) { @@ -1124,14 +1123,16 @@ class AnnouncementManager switch ($toGroup) { // it was send to one specific user case null: - $to[] = "USER:".$row['to_user_id']; + if (isset($row['to_user_id']) && !empty($row['to_user_id'])) { + $to[] = 'USER:'.$row['to_user_id']; + } break; // it was sent to everyone case 0: return 'everyone'; break; default: - $to[] = "GROUP:".$toGroup; + $to[] = 'GROUP:'.$toGroup; } } diff --git a/main/inc/lib/CourseChatUtils.php b/main/inc/lib/CourseChatUtils.php index e131bdf629..18ab921abf 100644 --- a/main/inc/lib/CourseChatUtils.php +++ b/main/inc/lib/CourseChatUtils.php @@ -4,7 +4,9 @@ use Chamilo\CoreBundle\Entity\Course; use Chamilo\CoreBundle\Entity\CourseRelUser; use Chamilo\CoreBundle\Entity\Session; +use Chamilo\CoreBundle\Entity\SessionRelCourseRelUser; use Chamilo\CourseBundle\Entity\CChatConnected; +use Chamilo\UserBundle\Entity\User; use Doctrine\Common\Collections\Criteria; use Michelf\MarkdownExtra; @@ -94,7 +96,7 @@ class CourseChatUtils $document_path = api_get_path(SYS_COURSE_PATH).$courseInfo['path'].'/document'; $basepath_chat = '/chat_files'; $group_info = []; - if (!$this->groupId) { + if ($this->groupId) { $group_info = GroupManager::get_group_properties($this->groupId); $basepath_chat = $group_info['directory'].'/chat_files'; } @@ -273,8 +275,6 @@ class CourseChatUtils /** * Keep registered to a user as connected. - * - * @throws \Doctrine\ORM\NonUniqueResultException */ public function keepUserAsConnected() { @@ -707,32 +707,63 @@ class CourseChatUtils /** * Get the users online data. * + * @throws \Doctrine\ORM\ORMException + * @throws \Doctrine\ORM\OptimisticLockException + * @throws \Doctrine\ORM\TransactionRequiredException + * * @return array */ public function listUsersOnline() { $subscriptions = $this->getUsersSubscriptions(); $usersInfo = []; - /** @var CourseRelUser $subscription */ - foreach ($subscriptions as $subscription) { - $user = $subscription->getUser(); - $usersInfo[] = [ - 'id' => $user->getId(), - 'firstname' => $user->getFirstname(), - 'lastname' => $user->getLastname(), - 'status' => !$this->sessionId ? $subscription->getStatus() : $user->getStatus(), - 'image_url' => UserManager::getUserPicture($user->getId(), USER_IMAGE_SIZE_MEDIUM), - 'profile_url' => api_get_path(WEB_CODE_PATH).'social/profile.php?u='.$user->getId(), - 'complete_name' => $user->getCompleteName(), - 'username' => $user->getUsername(), - 'email' => $user->getEmail(), - 'isConnected' => $this->userIsConnected($user->getId()), - ]; + + if ($this->groupId) { + /** @var User $groupUser */ + foreach ($subscriptions as $groupUser) { + $usersInfo[] = $this->formatUser( + $groupUser, + $groupUser->getStatus() + ); + } + } else { + /** @var CourseRelUser|SessionRelCourseRelUser $subscription */ + foreach ($subscriptions as $subscription) { + $user = $subscription->getUser(); + $usersInfo[] = $this->formatUser( + $user, + $this->sessionId ? $user->getStatus() : $subscription->getStatus() + ); + } } return $usersInfo; } + /** + * Format the user data to return it in the user list. + * + * @param User $user + * @param int $status + * + * @return array + */ + private function formatUser(User $user, $status) + { + return [ + 'id' => $user->getId(), + 'firstname' => $user->getFirstname(), + 'lastname' => $user->getLastname(), + 'status' => $status, + 'image_url' => UserManager::getUserPicture($user->getId(), USER_IMAGE_SIZE_MEDIUM), + 'profile_url' => api_get_path(WEB_CODE_PATH).'social/profile.php?u='.$user->getId(), + 'complete_name' => $user->getCompleteName(), + 'username' => $user->getUsername(), + 'email' => $user->getEmail(), + 'isConnected' => $this->userIsConnected($user->getId()), + ]; + } + /** * Get the users subscriptions (SessionRelCourseRelUser array or CourseRelUser array) for chat. * @@ -745,6 +776,30 @@ class CourseChatUtils private function getUsersSubscriptions() { $em = Database::getManager(); + + if ($this->groupId) { + $students = $em + ->createQuery( + 'SELECT u FROM ChamiloUserBundle:User u + INNER JOIN ChamiloCourseBundle:CGroupRelUser gru + WITH u.id = gru.userId AND gru.cId = :course + WHERE u.id != :user AND gru.groupId = :group' + ) + ->setParameters(['course' => $this->courseId, 'user' => $this->userId, 'group' => $this->groupId]) + ->getResult(); + $tutors = $em + ->createQuery( + 'SELECT u FROM ChamiloUserBundle:User u + INNER JOIN ChamiloCourseBundle:CGroupRelTutor grt + WITH u.id = grt.userId AND grt.cId = :course + WHERE u.id != :user AND grt.groupId = :group' + ) + ->setParameters(['course' => $this->courseId, 'user' => $this->userId, 'group' => $this->groupId]) + ->getResult(); + + return array_merge($tutors, $students); + } + /** @var Course $course */ $course = $em->find('ChamiloCoreBundle:Course', $this->courseId); diff --git a/main/inc/lib/CoursesAndSessionsCatalog.class.php b/main/inc/lib/CoursesAndSessionsCatalog.class.php index 34795e9248..feca55ad1e 100644 --- a/main/inc/lib/CoursesAndSessionsCatalog.class.php +++ b/main/inc/lib/CoursesAndSessionsCatalog.class.php @@ -24,7 +24,7 @@ class CoursesAndSessionsCatalog */ public static function is($value = CATALOG_COURSES) { - $showCoursesSessions = intval(api_get_setting('catalog_show_courses_sessions')); + $showCoursesSessions = (int) api_get_setting('catalog_show_courses_sessions'); if ($showCoursesSessions == $value) { return true; } @@ -41,7 +41,7 @@ class CoursesAndSessionsCatalog */ public static function showSessions() { - $catalogShow = intval(api_get_setting('catalog_show_courses_sessions')); + $catalogShow = (int) api_get_setting('catalog_show_courses_sessions'); if ($catalogShow == CATALOG_SESSIONS || $catalogShow == CATALOG_COURSES_SESSIONS) { return true; @@ -59,7 +59,7 @@ class CoursesAndSessionsCatalog */ public static function showCourses() { - $catalogShow = intval(api_get_setting('catalog_show_courses_sessions')); + $catalogShow = (int) api_get_setting('catalog_show_courses_sessions'); if ($catalogShow == CATALOG_COURSES || $catalogShow == CATALOG_COURSES_SESSIONS) { return true; diff --git a/main/inc/lib/ScheduledAnnouncement.php b/main/inc/lib/ScheduledAnnouncement.php index cf28e2c8c9..678b50a6fe 100644 --- a/main/inc/lib/ScheduledAnnouncement.php +++ b/main/inc/lib/ScheduledAnnouncement.php @@ -312,7 +312,7 @@ class ScheduledAnnouncement extends Model } $users = SessionManager::get_users_by_session( $sessionId, - '0', + 0, false, $urlId ); diff --git a/main/inc/lib/TicketManager.php b/main/inc/lib/TicketManager.php index 8691297cf6..92034b895a 100644 --- a/main/inc/lib/TicketManager.php +++ b/main/inc/lib/TicketManager.php @@ -196,7 +196,7 @@ class TicketManager $table = Database::get_main_table(TABLE_TICKET_CATEGORY_REL_USER); foreach ($users as $userId) { - if (self::userIsAssignedToCategory($userId, $categoryId) == false) { + if (self::userIsAssignedToCategory($userId, $categoryId) === false) { $params = [ 'category_id' => $categoryId, 'user_id' => $userId, @@ -217,8 +217,8 @@ class TicketManager public static function userIsAssignedToCategory($userId, $categoryId) { $table = Database::get_main_table(TABLE_TICKET_CATEGORY_REL_USER); - $userId = intval($userId); - $categoryId = intval($categoryId); + $userId = (int) $userId; + $categoryId = (int) $categoryId; $sql = "SELECT * FROM $table WHERE category_id = $categoryId AND user_id = $userId"; $result = Database::query($sql); @@ -234,7 +234,7 @@ class TicketManager public static function getUsersInCategory($categoryId) { $table = Database::get_main_table(TABLE_TICKET_CATEGORY_REL_USER); - $categoryId = intval($categoryId); + $categoryId = (int) $categoryId; $sql = "SELECT * FROM $table WHERE category_id = $categoryId"; $result = Database::query($sql); @@ -247,7 +247,7 @@ class TicketManager public static function deleteAllUserInCategory($categoryId) { $table = Database::get_main_table(TABLE_TICKET_CATEGORY_REL_USER); - $categoryId = intval($categoryId); + $categoryId = (int) $categoryId; $sql = "DELETE FROM $table WHERE category_id = $categoryId"; Database::query($sql); } @@ -583,8 +583,8 @@ class TicketManager $ticketId, $userId ) { - $ticketId = intval($ticketId); - $userId = intval($userId); + $ticketId = (int) $ticketId; + $userId = (int) $userId; if (empty($ticketId)) { return false; @@ -636,8 +636,8 @@ class TicketManager $status = 'NOL', $sendConfirmation = false ) { - $ticketId = intval($ticketId); - $userId = intval($userId); + $ticketId = (int) $ticketId; + $userId = (int) $userId; $table_support_messages = Database::get_main_table(TABLE_TICKET_MESSAGE); $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET); if ($sendConfirmation) { @@ -764,24 +764,26 @@ class TicketManager * @param int $number_of_items * @param $column * @param $direction - * @param int $userId * * @return array */ - public static function get_tickets_by_user_id( + public static function getTicketsByCurrentUser( $from, $number_of_items, $column, - $direction, - $userId = 0 + $direction ) { $table_support_category = Database::get_main_table(TABLE_TICKET_CATEGORY); $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET); $table_support_priority = Database::get_main_table(TABLE_TICKET_PRIORITY); $table_support_status = Database::get_main_table(TABLE_TICKET_STATUS); $direction = !empty($direction) ? $direction : 'DESC'; - $userId = !empty($userId) ? $userId : api_get_user_id(); + $userId = api_get_user_id(); $userInfo = api_get_user_info($userId); + + if (empty($userInfo)) { + return []; + } $isAdmin = UserManager::is_admin($userId); if (!isset($_GET['project_id'])) { @@ -995,11 +997,9 @@ class TicketManager } /** - * @param int $userId - * * @return int */ - public static function get_total_tickets_by_user_id($userId = 0) + public static function getTotalTicketsCurrentUser() { $table_support_category = Database::get_main_table(TABLE_TICKET_CATEGORY); $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET); @@ -1106,7 +1106,7 @@ class TicketManager /** * @param int $id * - * @return MessageAttachment + * @return false|MessageAttachment */ public static function getTicketMessageAttachment($id) { @@ -2428,6 +2428,7 @@ class TicketManager $allowRoleList = self::getAllowedRolesFromProject($projectId); // Check if a role was set to the project + // Project 1 is considered the default and is accessible to all users if (!empty($allowRoleList) && is_array($allowRoleList)) { if (in_array($userInfo['status'], $allowRoleList)) { return true; diff --git a/main/inc/lib/agenda.lib.php b/main/inc/lib/agenda.lib.php index 1690e688c1..1db03e2bbb 100644 --- a/main/inc/lib/agenda.lib.php +++ b/main/inc/lib/agenda.lib.php @@ -29,7 +29,7 @@ class Agenda * * @param string $type * @param int $senderId Optional The user sender ID - * @param int $courseId Opitonal. The course ID + * @param int $courseId Optional. The course ID * @param int $sessionId Optional The session ID */ public function __construct( @@ -84,10 +84,9 @@ class Agenda ); $isGroupAccess = $userHasAccess || $isTutor; + $isAllowToEdit = false; if ($isGroupAccess) { $isAllowToEdit = true; - } else { - $isAllowToEdit = false; } } @@ -111,7 +110,6 @@ class Agenda $this->setIsAllowedToEdit($isAllowToEdit); $this->events = []; - $agendaColors = array_merge( [ 'platform' => 'red', //red @@ -140,7 +138,7 @@ class Agenda */ public function setSenderId($senderId) { - $this->senderId = intval($senderId); + $this->senderId = (int) $senderId; } /** @@ -167,7 +165,7 @@ class Agenda */ public function setSessionId($id) { - $this->sessionId = intval($id); + $this->sessionId = (int) $id; } /** @@ -205,8 +203,8 @@ class Agenda /** * Adds an event to the calendar. * - * @param string $start datetime format: 2012-06-14 09:00:00 - * @param string $end datetime format: 2012-06-14 09:00:00 + * @param string $start datetime format: 2012-06-14 09:00:00 in local time + * @param string $end datetime format: 2012-06-14 09:00:00 in local time * @param string $allDay (true, false) * @param string $title * @param string $content @@ -324,12 +322,7 @@ class Agenda foreach ($sendTo['groups'] as $group) { $groupInfoItem = []; if ($group) { - $groupInfoItem = GroupManager::get_group_properties( - $group - ); - if ($groupInfoItem) { - $groupIidItem = $groupInfoItem['iid']; - } + $groupInfoItem = GroupManager::get_group_properties($group); } api_item_property_update( @@ -447,8 +440,8 @@ class Agenda public function getRepeatedInfoByEvent($eventId, $courseId) { $repeatTable = Database::get_course_table(TABLE_AGENDA_REPEAT); - $eventId = intval($eventId); - $courseId = intval($courseId); + $eventId = (int) $eventId; + $courseId = (int) $courseId; $sql = "SELECT * FROM $repeatTable WHERE c_id = $courseId AND cal_id = $eventId"; $res = Database::query($sql); @@ -460,10 +453,111 @@ class Agenda return $repeatInfo; } + /** + * @param string $type + * @param string $startEvent in UTC + * @param string $endEvent in UTC + * @param string $repeatUntilDate in UTC + * + * @throws Exception + * + * @return array + */ + public function generateDatesByType($type, $startEvent, $endEvent, $repeatUntilDate) + { + $continue = true; + $repeatUntilDate = new DateTime($repeatUntilDate, new DateTimeZone('UTC')); + $loopMax = 365; + $counter = 0; + $list = []; + + switch ($type) { + case 'daily': + $interval = 'P1D'; + break; + case 'weekly': + $interval = 'P1W'; + break; + case 'monthlyByDate': + $interval = 'P1M'; + break; + case 'monthlyByDay': + // not yet implemented + break; + case 'monthlyByDayR': + // not yet implemented + break; + case 'yearly': + $interval = 'P1Y'; + break; + } + + if (empty($interval)) { + return []; + } + $timeZone = api_get_timezone(); + + while ($continue) { + $startDate = new DateTime($startEvent, new DateTimeZone('UTC')); + $endDate = new DateTime($endEvent, new DateTimeZone('UTC')); + + $startDate->add(new DateInterval($interval)); + $endDate->add(new DateInterval($interval)); + + $newStartDate = $startDate->format('Y-m-d H:i:s'); + $newEndDate = $endDate->format('Y-m-d H:i:s'); + + $startEvent = $newStartDate; + $endEvent = $newEndDate; + + if ($endDate > $repeatUntilDate) { + break; + } + + // @todo remove comment code + $startDateInLocal = new DateTime($newStartDate, new DateTimeZone($timeZone)); + //$originalOffset = $startDate->getOffset(); + if ($startDateInLocal->format('I') == 0) { + // Is saving time? Then fix UTC time to add time + $seconds = $startDateInLocal->getOffset(); + $startDate->add(new DateInterval("PT".$seconds."S")); + $startDateFixed = $startDate->format('Y-m-d H:i:s'); + $startDateInLocalFixed = new DateTime($startDateFixed, new DateTimeZone($timeZone)); + $newStartDate = $startDateInLocalFixed->format('Y-m-d H:i:s'); + } else { + /*$seconds = $startDateInLocal->getOffset(); + $startDate->add(new DateInterval("PT".$seconds."S")); + $startDateFixed = $startDate->format('Y-m-d H:i:s'); + $startDateInLocalFixed = new DateTime($startDateFixed, new DateTimeZone($timeZone)); + $newStartDate = $startDateInLocalFixed->format('Y-m-d H:i:s');*/ + } + //var_dump($newStartDate.' - '.$startDateInLocal->format('I')); + $endDateInLocal = new DateTime($newEndDate, new DateTimeZone($timeZone)); + + if ($endDateInLocal->format('I') == 0) { + // Is saving time? Then fix UTC time to add time + $seconds = $endDateInLocal->getOffset(); + $endDate->add(new DateInterval("PT".$seconds."S")); + $endDateFixed = $endDate->format('Y-m-d H:i:s'); + $endDateInLocalFixed = new DateTime($endDateFixed, new DateTimeZone($timeZone)); + $newEndDate = $endDateInLocalFixed->format('Y-m-d H:i:s'); + } + $list[] = ['start' => $newStartDate, 'end' => $newEndDate, 'i' => $startDateInLocal->format('I')]; + $counter++; + + // just in case stop if more than $loopMax + if ($counter > $loopMax) { + break; + } + } + + return $list; + } + /** * @param int $eventId * @param string $type - * @param string $end in local time + * @param string $end in UTC * @param array $sentTo * * @return bool @@ -477,56 +571,18 @@ class Agenda return false; } - $course_id = $this->course['real_id']; - $eventId = intval($eventId); + $courseId = $this->course['real_id']; + $eventId = (int) $eventId; $sql = "SELECT title, content, start_date, end_date, all_day FROM $t_agenda - WHERE c_id = $course_id AND id = $eventId"; + WHERE c_id = $courseId AND id = $eventId"; $res = Database::query($sql); if (Database::num_rows($res) !== 1) { return false; } - $row = Database::fetch_array($res); - $origStartDate = api_strtotime($row['start_date'], 'UTC'); - $origEndDate = api_strtotime($row['end_date'], 'UTC'); - $diff = $origEndDate - $origStartDate; - - $title = $row['title']; - $content = $row['content']; - $allDay = $row['all_day']; - - $now = time(); - $type = Database::escape_string($type); - $end = api_strtotime($end); - - if (1 <= $end && $end <= 500) { - // We assume that, with this type of value, the user actually gives a count of repetitions - //and that he wants us to calculate the end date with that (particularly in case of imports from ical) - switch ($type) { - case 'daily': - $end = $origStartDate + (86400 * $end); - break; - case 'weekly': - $end = $this->addWeek($origStartDate, $end); - break; - case 'monthlyByDate': - $end = $this->addMonth($origStartDate, $end); - break; - case 'monthlyByDay': - //TODO - break; - case 'monthlyByDayR': - //TODO - break; - case 'yearly': - $end = $this->addYear($origStartDate, $end); - break; - } - } - $typeList = [ 'daily', 'weekly', @@ -536,90 +592,50 @@ class Agenda 'yearly', ]; + if (!in_array($type, $typeList)) { + return false; + } + + $now = time(); + // The event has to repeat *in the future*. We don't allow repeated // events in the past - if ($end > $now && in_array($type, $typeList)) { - $sql = "INSERT INTO $t_agenda_r (c_id, cal_id, cal_type, cal_end) - VALUES ($course_id, '$eventId', '$type', '$end')"; - Database::query($sql); - - switch ($type) { - // @todo improve loop. - case 'daily': - for ($i = $origStartDate + 86400; $i <= $end; $i += 86400) { - $start = date('Y-m-d H:i:s', $i); - $repeatEnd = date('Y-m-d H:i:s', $i + $diff); - $this->addEvent( - $start, - $repeatEnd, - $allDay, - $title, - $content, - $sentTo, - false, - $eventId - ); - } - break; - case 'weekly': - for ($i = $origStartDate + 604800; $i <= $end; $i += 604800) { - $start = date('Y-m-d H:i:s', $i); - $repeatEnd = date('Y-m-d H:i:s', $i + $diff); - $this->addEvent( - $start, - $repeatEnd, - $allDay, - $title, - $content, - $sentTo, - false, - $eventId - ); - } - break; - case 'monthlyByDate': - $next_start = $this->addMonth($origStartDate); - while ($next_start <= $end) { - $start = date('Y-m-d H:i:s', $next_start); - $repeatEnd = date('Y-m-d H:i:s', $next_start + $diff); - $this->addEvent( - $start, - $repeatEnd, - $allDay, - $title, - $content, - $sentTo, - false, - $eventId - ); - $next_start = $this->addMonth($next_start); - } - break; - case 'monthlyByDay': - //not yet implemented - break; - case 'monthlyByDayR': - //not yet implemented - break; - case 'yearly': - $next_start = $this->addYear($origStartDate); - while ($next_start <= $end) { - $start = date('Y-m-d H:i:s', $next_start); - $repeatEnd = date('Y-m-d H:i:s', $next_start + $diff); - $this->addEvent( - $start, - $repeatEnd, - $allDay, - $title, - $content, - $sentTo, - false, - $eventId - ); - $next_start = $this->addYear($next_start); - } - break; - } + if ($end > $now) { + return false; + } + + $row = Database::fetch_array($res); + + $title = $row['title']; + $content = $row['content']; + $allDay = $row['all_day']; + + $type = Database::escape_string($type); + $end = Database::escape_string($end); + $endTimeStamp = api_strtotime($end, 'UTC'); + $sql = "INSERT INTO $t_agenda_r (c_id, cal_id, cal_type, cal_end) + VALUES ($courseId, '$eventId', '$type', '$endTimeStamp')"; + Database::query($sql); + + $generatedDates = $this->generateDatesByType($type, $row['start_date'], $row['end_date'], $end); + + if (empty($generatedDates)) { + return false; + } + + foreach ($generatedDates as $dateInfo) { + $start = api_get_local_time($dateInfo['start']); + $end = api_get_local_time($dateInfo['end']); + $this->addEvent( + $start, + $end, + $allDay, + $title, + $content, + $sentTo, + false, + $eventId + ); } return true; @@ -634,7 +650,7 @@ class Agenda public function storeAgendaEventAsAnnouncement($item_id, $sentTo = []) { $table_agenda = Database::get_course_table(TABLE_AGENDA); - $course_id = api_get_course_int_id(); + $courseId = api_get_course_int_id(); // Check params if (empty($item_id) || $item_id != strval(intval($item_id))) { @@ -644,7 +660,7 @@ class Agenda // Get the agenda item. $item_id = intval($item_id); $sql = "SELECT * FROM $table_agenda - WHERE c_id = $course_id AND id = ".$item_id; + WHERE c_id = $courseId AND id = ".$item_id; $res = Database::query($sql); if (Database::num_rows($res) > 0) { @@ -761,9 +777,9 @@ class Agenda } } - $course_id = $this->course['real_id']; + $courseId = $this->course['real_id']; - if (empty($course_id)) { + if (empty($courseId)) { return false; } @@ -790,7 +806,7 @@ class Agenda [ 'id = ? AND c_id = ? AND session_id = ? ' => [ $id, - $course_id, + $courseId, $this->sessionId, ], ] @@ -1036,7 +1052,7 @@ class Agenda } break; case 'course': - $course_id = api_get_course_int_id(); + $courseId = api_get_course_int_id(); $sessionId = api_get_session_id(); $isAllowToEdit = api_is_allowed_to_edit(null, true); @@ -1053,7 +1069,7 @@ class Agenda } } - if (!empty($course_id) && $isAllowToEdit) { + if (!empty($courseId) && $isAllowToEdit) { // Delete $eventInfo = $this->get_event($id); if ($deleteAllItemsFromSerie) { @@ -1085,7 +1101,7 @@ class Agenda // Removing from events. Database::delete( $this->tbl_course_agenda, - ['id = ? AND c_id = ?' => [$id, $course_id]] + ['id = ? AND c_id = ?' => [$id, $courseId]] ); api_item_property_update( @@ -1102,7 +1118,7 @@ class Agenda [ 'cal_id = ? AND c_id = ?' => [ $id, - $course_id, + $courseId, ], ] ); @@ -1133,7 +1149,7 @@ class Agenda * * @param int $start * @param int $end - * @param int $course_id + * @param int $courseId * @param int $groupId * @param int $user_id * @param string $format @@ -1143,7 +1159,7 @@ class Agenda public function getEvents( $start, $end, - $course_id = null, + $courseId = null, $groupId = null, $user_id = 0, $format = 'json' @@ -1153,7 +1169,7 @@ class Agenda $this->getPlatformEvents($start, $end); break; case 'course': - $courseInfo = api_get_course_info_by_id($course_id); + $courseInfo = api_get_course_info_by_id($courseId); // Session coach can see all events inside a session. if (api_is_coach()) { @@ -1277,8 +1293,8 @@ class Agenda $courseInfo = api_get_course_info_by_id( $courseInfoItem['real_id'] ); - if (isset($course_id) && !empty($course_id)) { - if ($courseInfo['real_id'] == $course_id) { + if (isset($courseId) && !empty($courseId)) { + if ($courseInfo['real_id'] == $courseId) { $this->getCourseEvents( $start, $end, @@ -1498,18 +1514,16 @@ class Agenda */ public function getPersonalEvents($start, $end) { - $start = intval($start); - $end = intval($end); + $start = (int) $start; + $end = (int) $end; $startCondition = ''; $endCondition = ''; if ($start !== 0) { - $start = api_get_utc_datetime($start); - $startCondition = "AND date >= '".$start."'"; + $startCondition = "AND date >= '".api_get_utc_datetime($start)."'"; } if ($start !== 0) { - $end = api_get_utc_datetime($end); - $endCondition = "AND (enddate <= '".$end."' OR enddate IS NULL)"; + $endCondition = "AND (enddate <= '".api_get_utc_datetime($end)."' OR enddate IS NULL)"; } $user_id = api_get_user_id(); @@ -1531,16 +1545,12 @@ class Agenda if (!empty($row['date'])) { $event['start'] = $this->formatEventDate($row['date']); - $event['start_date_localtime'] = api_get_local_time( - $row['date'] - ); + $event['start_date_localtime'] = api_get_local_time($row['date']); } if (!empty($row['enddate'])) { $event['end'] = $this->formatEventDate($row['enddate']); - $event['end_date_localtime'] = api_get_local_time( - $row['enddate'] - ); + $event['end_date_localtime'] = api_get_local_time($row['enddate']); } $event['description'] = $row['text']; @@ -1553,6 +1563,21 @@ class Agenda } } + // Add plugin personal events + + $this->plugin = new AppPlugin(); + $plugins = $this->plugin->getInstalledPluginListObject(); + /** @var Plugin $plugin */ + foreach ($plugins as $plugin) { + if ($plugin->hasPersonalEvents && method_exists($plugin, 'getPersonalEvents')) { + $pluginEvents = $plugin->getPersonalEvents($this, $start, $end); + + if (!empty($pluginEvents)) { + $this->events = array_merge($this->events, $pluginEvents); + } + } + } + return $my_events; } @@ -1957,18 +1982,12 @@ class Agenda } if (!empty($row['start_date'])) { - $event['start'] = $this->formatEventDate( - $row['start_date'] - ); - $event['start_date_localtime'] = api_get_local_time( - $row['start_date'] - ); + $event['start'] = $this->formatEventDate($row['start_date']); + $event['start_date_localtime'] = api_get_local_time($row['start_date']); } if (!empty($row['end_date'])) { $event['end'] = $this->formatEventDate($row['end_date']); - $event['end_date_localtime'] = api_get_local_time( - $row['end_date'] - ); + $event['end_date_localtime'] = api_get_local_time($row['end_date']); } $event['sent_to'] = ''; @@ -2083,7 +2102,7 @@ class Agenda $event['editable'] = false; $event['type'] = 'admin'; - if (api_is_platform_admin() && $this->type == 'admin') { + if (api_is_platform_admin() && $this->type === 'admin') { $event['editable'] = true; } @@ -2283,7 +2302,7 @@ class Agenda public function getForm($params = []) { $action = isset($params['action']) ? Security::remove_XSS($params['action']) : null; - $id = isset($params['id']) ? intval($params['id']) : null; + $id = isset($params['id']) ? (int) $params['id'] : 0; if ($this->type == 'course') { $url = api_get_self().'?'.api_get_cidreq().'&action='.$action.'&id='.$id.'&type='.$this->type; @@ -2299,18 +2318,14 @@ class Agenda ['enctype' => 'multipart/form-data'] ); - $idAttach = isset($params['id_attach']) ? intval( - $params['id_attach'] - ) : null; + $idAttach = isset($params['id_attach']) ? (int) $params['id_attach'] : null; $groupId = api_get_group_id(); - - if ($id) { - $form_title = get_lang('ModifyCalendarItem'); - } else { - $form_title = get_lang('AddCalendarItem'); + $form_Title = get_lang('AddCalendarItem'); + if (!empty($id)) { + $form_Title = get_lang('ModifyCalendarItem'); } - $form->addElement('header', $form_title); + $form->addHeader($form_Title); $form->addElement('hidden', 'id', $id); $form->addElement('hidden', 'action', $action); $form->addElement('hidden', 'id_attach', $idAttach); @@ -2393,11 +2408,10 @@ class Agenda ); if ($isSubEventEdition || $isParentFromSerie) { + $repeatInfo = $params['repeat_info']; if ($isSubEventEdition) { $parentEvent = $params['parent_info']; $repeatInfo = $parentEvent['repeat_info']; - } else { - $repeatInfo = $params['repeat_info']; } $params['repeat'] = 1; $params['repeat_type'] = $repeatInfo['cal_type']; @@ -2423,10 +2437,9 @@ class Agenda substr(api_get_local_time($params['end_date']), 0, 16); } + $toolbar = 'Agenda'; if (!api_is_allowed_to_edit(null, true)) { $toolbar = 'AgendaStudent'; - } else { - $toolbar = 'Agenda'; } $form->addElement( @@ -2732,12 +2745,12 @@ class Agenda $fileUserUpload['tmp_name'], $new_path ); - $course_id = api_get_course_int_id(); + $courseId = api_get_course_int_id(); $size = intval($fileUserUpload['size']); // Storing the attachments if any if ($result) { $params = [ - 'c_id' => $course_id, + 'c_id' => $courseId, 'filename' => $file_name, 'comment' => $comment, 'path' => $new_file_name, @@ -2827,61 +2840,6 @@ class Agenda } } - /** - * Adds x weeks to a UNIX timestamp. - * - * @param int $timestamp The timestamp - * @param int $num The number of weeks to add - * - * @return int The new timestamp - */ - public function addWeek($timestamp, $num = 1) - { - return $timestamp + $num * 604800; - } - - /** - * Adds x months to a UNIX timestamp. - * - * @param int $timestamp The timestamp - * @param int $num The number of years to add - * - * @return int The new timestamp - */ - public function addMonth($timestamp, $num = 1) - { - list($y, $m, $d, $h, $n, $s) = split( - '/', - date('Y/m/d/h/i/s', $timestamp) - ); - if ($m + $num > 12) { - $y += floor($num / 12); - $m += $num % 12; - } else { - $m += $num; - } - - return mktime($h, $n, $s, $m, $d, $y); - } - - /** - * Adds x years to a UNIX timestamp. - * - * @param int $timestamp The timestamp - * @param int $num The number of years to add - * - * @return int The new timestamp - */ - public function addYear($timestamp, $num = 1) - { - list($y, $m, $d, $h, $n, $s) = split( - '/', - date('Y/m/d/h/i/s', $timestamp) - ); - - return mktime($h, $n, $s, $m, $d, $y + $num); - } - /** * @param int $eventId * @@ -3202,8 +3160,7 @@ class Agenda $repeat['UNTIL'], new DateTimeZone($currentTimeZone) ); - $until = $until->format('Y-m-d H:i'); - //$res = agenda_add_repeat_item($courseInfo, $id, $freq, $until, $attendee); + $until = $until->format('Y-m-d H:i:s'); $this->addRepeatedItem( $id, $freq, @@ -3554,7 +3511,8 @@ class Agenda } /** - * This function retrieves all the personal agenda items and add them to the agenda items found by the other functions. + * This function retrieves all the personal agenda items and add them to the agenda items found by the other + * functions. */ public static function get_personal_agenda_items( $user_id, @@ -3677,7 +3635,8 @@ class Agenda * @param array Agendaitems * @param int Month number * @param int Year number - * @param array Array of strings containing long week day names (deprecated, you can send an empty array instead) + * @param array Array of strings containing long week day names (deprecated, you can send an empty array + * instead) * @param string The month name */ public static function display_mymonthcalendar( @@ -4044,12 +4003,12 @@ class Agenda )."main/calendar/agenda.php?cidReq=".urlencode( $course["code"] )."&day=$agendaday&month=$month&year=$year#$agendaday"; - list($year, $month, $day, $hour, $min, $sec) = split( + list($year, $month, $day, $hour, $min, $sec) = explode( '[-: ]', $item['start_date'] ); $start_date = $year.$month.$day.$hour.$min; - list($year, $month, $day, $hour, $min, $sec) = split( + list($year, $month, $day, $hour, $min, $sec) = explode( '[-: ]', $item['end_date'] ); @@ -4077,11 +4036,11 @@ class Agenda */ public static function get_personal_agenda_item($id) { - $tbl_personal_agenda = Database::get_main_table(TABLE_PERSONAL_AGENDA); + $table = Database::get_main_table(TABLE_PERSONAL_AGENDA); $id = intval($id); // make sure events of the personal agenda can only be seen by the user himself $user = api_get_user_id(); - $sql = " SELECT * FROM ".$tbl_personal_agenda." WHERE id=".$id." AND user = ".$user; + $sql = " SELECT * FROM ".$table." WHERE id=".$id." AND user = ".$user; $result = Database::query($sql); if (Database::num_rows($result) == 1) { $item = Database::fetch_array($result); @@ -4155,7 +4114,7 @@ class Agenda * * @return bool|string */ - private function formatEventDate($utcTime) + public function formatEventDate($utcTime) { $utcTimeZone = new DateTimeZone('UTC'); $platformTimeZone = new DateTimeZone(api_get_timezone()); diff --git a/main/inc/lib/api.lib.php b/main/inc/lib/api.lib.php index 80c13fe91a..308f110bb1 100644 --- a/main/inc/lib/api.lib.php +++ b/main/inc/lib/api.lib.php @@ -196,12 +196,14 @@ define('LOG_USER_DELETE', 'user_deleted'); define('LOG_USER_CREATE', 'user_created'); define('LOG_USER_ENABLE', 'user_enable'); define('LOG_USER_DISABLE', 'user_disable'); +define('LOG_USER_ANONYMIZE', 'user_anonymized'); define('LOG_USER_FIELD_CREATE', 'user_field_created'); define('LOG_USER_FIELD_DELETE', 'user_field_deleted'); define('LOG_SESSION_CREATE', 'session_created'); define('LOG_SESSION_DELETE', 'session_deleted'); define('LOG_SESSION_ADD_USER_COURSE', 'session_add_user_course'); define('LOG_SESSION_DELETE_USER_COURSE', 'session_delete_user_course'); +define('LOG_SESSION_ADD_USER', 'session_add_user'); define('LOG_SESSION_DELETE_USER', 'session_delete_user'); define('LOG_SESSION_ADD_COURSE', 'session_add_course'); define('LOG_SESSION_DELETE_COURSE', 'session_delete_course'); @@ -270,6 +272,12 @@ define('LOG_WORK_DATA', 'work_data_array'); define('LOG_MY_FOLDER_PATH', 'path'); define('LOG_MY_FOLDER_NEW_PATH', 'new_path'); +define('LOG_TERM_CONDITION_ACCEPTED', 'term_condition_accepted'); +define('LOG_USER_CONFIRMED_EMAIL', 'user_confirmed_email'); +define('LOG_USER_REMOVED_LEGAL_ACCEPT', 'user_removed_legal_accept'); + +define('LOG_USER_DELETE_ACCOUNT_REQUEST', 'user_delete_account_request'); + define('USERNAME_PURIFIER', '/[^0-9A-Za-z_\.]/'); //used when login_is_email setting is true @@ -460,7 +468,8 @@ define('RESULT_DISABLE_SHOW_SCORE_AND_EXPECTED_ANSWERS', 0); //show score and ex define('RESULT_DISABLE_NO_SCORE_AND_EXPECTED_ANSWERS', 1); //Do not show score nor answers define('RESULT_DISABLE_SHOW_SCORE_ONLY', 2); //Show score only define('RESULT_DISABLE_SHOW_FINAL_SCORE_ONLY_WITH_CATEGORIES', 3); //Show final score only with categories -define('RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT', 4); //Show final score only with categories +define('RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT', 4); +// 4: Show final score only with categories and show expected answers only on the last attempt define('EXERCISE_MAX_NAME_SIZE', 80); @@ -487,6 +496,7 @@ define('DRAGGABLE', 18); define('MATCHING_DRAGGABLE', 19); define('ANNOTATION', 20); define('READING_COMPREHENSION', 21); +define('MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY', 22); define('EXERCISE_CATEGORY_RANDOM_SHUFFLED', 1); define('EXERCISE_CATEGORY_RANDOM_ORDERED', 2); @@ -538,6 +548,7 @@ define( UNIQUE_ANSWER_IMAGE.':'. DRAGGABLE.':'. MATCHING_DRAGGABLE.':'. + MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY.':'. ANNOTATION ); @@ -620,6 +631,7 @@ define('RESOURCE_EVENT', 'calendar_event'); define('RESOURCE_LINK', 'link'); define('RESOURCE_COURSEDESCRIPTION', 'course_description'); define('RESOURCE_LEARNPATH', 'learnpath'); +define('RESOURCE_LEARNPATH_CATEGORY', 'learnpath_category'); define('RESOURCE_ANNOUNCEMENT', 'announcement'); define('RESOURCE_FORUM', 'forum'); define('RESOURCE_FORUMTOPIC', 'thread'); @@ -1493,7 +1505,7 @@ function _api_format_user($user, $add_password = false, $loadAvatars = true) $result[$attribute] = isset($user[$attribute]) ? $user[$attribute] : null; } - $user_id = intval($user['user_id']); + $user_id = (int) $user['user_id']; // Maintain the user_id index for backwards compatibility $result['user_id'] = $result['id'] = $user_id; @@ -1549,7 +1561,7 @@ function _api_format_user($user, $add_password = false, $loadAvatars = true) $result['user_is_online'] = $user['user_is_online'] == true ? 1 : 0; } if (isset($user['user_is_online_in_chat'])) { - $result['user_is_online_in_chat'] = intval($user['user_is_online_in_chat']); + $result['user_is_online_in_chat'] = (int) $user['user_is_online_in_chat']; } if ($add_password) { @@ -1643,7 +1655,7 @@ function api_get_user_info( } // Make sure user_id is safe - $user_id = intval($user_id); + $user_id = (int) $user_id; // Re-use user information if not stale and already stored in APCu if ($cacheAvailable === true) { @@ -1672,7 +1684,7 @@ function api_get_user_info( false, true ); - if (@intval($user_status['user_chat_status']) == 1) { + if ((int) $user_status['user_chat_status'] == 1) { $user_online_in_chat = 1; } } @@ -1704,10 +1716,12 @@ function api_get_user_info( function api_get_user_entity($userId) { $userId = (int) $userId; - /** @var \Chamilo\UserBundle\Repository\UserRepository $repo */ - $repo = Database::getManager()->getRepository('ChamiloUserBundle:User'); + $repo = UserManager::getRepository(); + + /** @var User $user */ + $user = $repo->find($userId); - return $repo->find($userId); + return $user; } /** @@ -1715,7 +1729,7 @@ function api_get_user_entity($userId) * * @param string $username * - * @return array $user_info array user_id, lastname, firstname, username, email + * @return mixed $user_info array user_id, lastname, firstname, username, email or false on error * * @author Yannick Warnier */ @@ -1730,9 +1744,9 @@ function api_get_user_info_from_username($username = '') WHERE username='".Database::escape_string($username)."'"; $result = Database::query($sql); if (Database::num_rows($result) > 0) { - $result_array = Database::fetch_array($result); + $resultArray = Database::fetch_array($result); - return _api_format_user($result_array); + return _api_format_user($resultArray); } return false; @@ -1754,9 +1768,9 @@ function api_get_user_info_from_email($email = '') WHERE email ='".Database::escape_string($email)."' LIMIT 1"; $result = Database::query($sql); if (Database::num_rows($result) > 0) { - $result_array = Database::fetch_array($result); + $resultArray = Database::fetch_array($result); - return _api_format_user($result_array); + return _api_format_user($resultArray); } return false; @@ -1949,8 +1963,8 @@ function api_get_cidreq_params($courseCode, $sessionId = 0, $groupId = 0) function api_get_cidreq($addSessionId = true, $addGroupId = true, $origin = '') { $courseCode = api_get_course_id(); - $url = empty($courseCode) ? '' : 'cidReq='.htmlspecialchars($courseCode, ENT_QUOTES); - $origin = empty($origin) ? api_get_origin() : htmlspecialchars($origin, ENT_QUOTES); + $url = empty($courseCode) ? '' : 'cidReq='.htmlspecialchars($courseCode); + $origin = empty($origin) ? api_get_origin() : Security::remove_XSS($origin); if ($addSessionId) { if (!empty($url)) { @@ -2089,7 +2103,7 @@ function api_get_session_entity($id = 0) function api_get_course_info_by_id($id = null) { if (!empty($id)) { - $id = intval($id); + $id = (int) $id; $course_table = Database::get_main_table(TABLE_MAIN_COURSE); $course_cat_table = Database::get_main_table(TABLE_MAIN_CATEGORY); $sql = "SELECT @@ -2393,10 +2407,8 @@ function get_status_from_code($status_code) switch ($status_code) { case STUDENT: return get_lang('Student', ''); - case TEACHER: - return get_lang('Teacher', ''); case COURSEMANAGER: - return get_lang('Manager', ''); + return get_lang('Teacher', ''); case SESSIONADMIN: return get_lang('SessionsAdmin', ''); case DRH: @@ -2531,7 +2543,7 @@ function api_get_session_visibility( return 0; // Means that the session is still available. } - $session_id = intval($session_id); + $session_id = (int) $session_id; $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION); $result = Database::query("SELECT * FROM $tbl_session WHERE id = $session_id"); @@ -2575,6 +2587,7 @@ function api_get_session_visibility( return SESSION_AVAILABLE; } + // If start date was set. if (!empty($row['access_start_date'])) { $visibility = $now > api_strtotime($row['access_start_date'], 'UTC') ? SESSION_AVAILABLE : SESSION_INVISIBLE; @@ -2590,8 +2603,7 @@ function api_get_session_visibility( } } - /* If I'm a coach the visibility can change in my favor depending in - the coach dates */ + // If I'm a coach the visibility can change in my favor depending in the coach dates. $isCoach = api_is_coach($session_id, $courseId); if ($isCoach) { @@ -2657,7 +2669,7 @@ function api_get_session_condition( $with_base_content = false, $session_field = 'session_id' ) { - $session_id = intval($session_id); + $session_id = (int) $session_id; if (empty($session_field)) { $session_field = "session_id"; @@ -2938,7 +2950,7 @@ function api_is_platform_admin($allowSessionAdmins = false, $allowDrh = false) */ function api_is_platform_admin_by_id($user_id = null, $url = null) { - $user_id = intval($user_id); + $user_id = (int) $user_id; if (empty($user_id)) { $user_id = api_get_user_id(); } @@ -2950,7 +2962,7 @@ function api_is_platform_admin_by_id($user_id = null, $url = null) return $is_admin; } // We get here only if $url is set - $url = intval($url); + $url = (int) $url; $url_user_table = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER); $sql = "SELECT * FROM $url_user_table WHERE access_url_id = $url AND user_id = $user_id"; @@ -2969,7 +2981,7 @@ function api_is_platform_admin_by_id($user_id = null, $url = null) */ function api_get_user_status($user_id = null) { - $user_id = intval($user_id); + $user_id = (int) $user_id; if (empty($user_id)) { $user_id = api_get_user_id(); } @@ -3057,9 +3069,9 @@ function api_is_course_session_coach($user_id, $courseId, $session_id) $session_table = Database::get_main_table(TABLE_MAIN_SESSION); $session_rel_course_rel_user_table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER); - $user_id = intval($user_id); - $session_id = intval($session_id); - $courseId = intval($courseId); + $user_id = (int) $user_id; + $session_id = (int) $session_id; + $courseId = (int) $courseId; $sql = "SELECT DISTINCT session.id FROM $session_table @@ -3089,7 +3101,7 @@ function api_is_coach($session_id = 0, $courseId = null, $check_student_view = t $userId = api_get_user_id(); if (!empty($session_id)) { - $session_id = intval($session_id); + $session_id = (int) $session_id; } else { $session_id = api_get_session_id(); } @@ -3100,7 +3112,7 @@ function api_is_coach($session_id = 0, $courseId = null, $check_student_view = t } if (!empty($courseId)) { - $courseId = intval($courseId); + $courseId = (int) $courseId; } else { $courseId = api_get_course_int_id(); } @@ -3211,7 +3223,7 @@ function api_is_invitee() */ function api_is_session_in_category($session_id, $category_name) { - $session_id = intval($session_id); + $session_id = (int) $session_id; $category_name = Database::escape_string($category_name); $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION); $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY); @@ -3401,6 +3413,19 @@ function api_is_allowed_to_edit( } $sessionId = api_get_session_id(); + + if ($sessionId && api_get_configuration_value('session_courses_read_only_mode')) { + $efv = new ExtraFieldValue('course'); + $lockExrafieldField = $efv->get_values_by_handler_and_field_variable( + api_get_course_int_id(), + 'session_courses_read_only_mode' + ); + + if (!empty($lockExrafieldField['value'])) { + return false; + } + } + $is_allowed_coach_to_edit = api_is_coach(null, null, $check_student_view); $session_visibility = api_get_session_visibility($sessionId); $is_courseAdmin = api_is_course_admin(); @@ -3554,10 +3579,6 @@ function api_is_allowed_to_session_edit($tutor = false, $coach = false) // Get the session visibility $session_visibility = api_get_session_visibility($sessionId); // if 5 the session is still available - //@todo We could load the session_rel_course_rel_user permission to increase the level of detail. - //echo api_get_user_id(); - //echo api_get_course_id(); - switch ($session_visibility) { case SESSION_VISIBLE_READ_ONLY: // 1 return false; @@ -3990,14 +4011,14 @@ function api_get_item_visibility( } $tool = Database::escape_string($tool); - $id = intval($id); + $id = (int) $id; $session = (int) $session; $TABLE_ITEMPROPERTY = Database::get_course_table(TABLE_ITEM_PROPERTY); - $course_id = intval($_course['real_id']); + $course_id = (int) $_course['real_id']; $userCondition = ''; if (!empty($user_id)) { - $user_id = intval($user_id); + $user_id = (int) $user_id; $userCondition = " AND to_user_id = $user_id "; } @@ -4009,7 +4030,7 @@ function api_get_item_visibility( $groupCondition = ''; if (!empty($group_id)) { - $group_id = intval($group_id); + $group_id = (int) $group_id; $groupCondition = " AND to_group_id = '$group_id' "; } @@ -4030,7 +4051,7 @@ function api_get_item_visibility( } $row = Database::fetch_array($res); - return $row['visibility']; + return (int) $row['visibility']; } /** @@ -4057,7 +4078,7 @@ function api_item_property_delete( return false; } - $courseId = intval($courseInfo['real_id']); + $courseId = (int) $courseInfo['real_id']; if (empty($courseId) || empty($tool) || empty($itemId)) { return false; @@ -4171,7 +4192,7 @@ function api_item_property_update( $time = api_get_utc_datetime(); if (!empty($session_id)) { - $session_id = intval($session_id); + $session_id = (int) $session_id; } else { $session_id = api_get_session_id(); } @@ -4185,7 +4206,7 @@ function api_item_property_update( if (!is_null($to_user_id)) { // $to_user_id has more priority than $to_group_id - $to_user_id = intval($to_user_id); + $to_user_id = (int) $to_user_id; $to_field = 'to_user_id'; $to_value = $to_user_id; } else { @@ -4194,11 +4215,11 @@ function api_item_property_update( $to_value = $to_group_id; } - $toValueCondition = empty($to_value) ? "NULL" : "'$to_value'"; + $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) "; + $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 "; @@ -4437,7 +4458,7 @@ function api_get_item_property_by_tool($tool, $course_code, $session_id = null) // Definition of tables. $item_property_table = Database::get_course_table(TABLE_ITEM_PROPERTY); - $session_id = intval($session_id); + $session_id = (int) $session_id; $session_condition = ' AND session_id = '.$session_id; if (empty($session_id)) { $session_condition = " AND (session_id = 0 OR session_id IS NULL) "; @@ -4519,7 +4540,7 @@ function api_get_item_property_id($course_code, $tool, $ref, $sessionId = 0) { $course_info = api_get_course_info($course_code); $tool = Database::escape_string($tool); - $ref = intval($ref); + $ref = (int) $ref; // Definition of tables. $tableItemProperty = Database::get_course_table(TABLE_ITEM_PROPERTY); @@ -4527,7 +4548,7 @@ function api_get_item_property_id($course_code, $tool, $ref, $sessionId = 0) $sessionId = (int) $sessionId; $sessionCondition = " AND session_id = $sessionId "; if (empty($sessionId)) { - $sessionCondition = " AND (session_id = 0 OR session_id IS NULL) "; + $sessionCondition = ' AND (session_id = 0 OR session_id IS NULL) '; } $sql = "SELECT id FROM $tableItemProperty WHERE @@ -4626,13 +4647,13 @@ function api_get_item_property_info($course_id, $tool, $ref, $session_id = 0, $g } $tool = Database::escape_string($tool); - $ref = intval($ref); $course_id = $courseInfo['real_id']; - $session_id = intval($session_id); + $ref = (int) $ref; + $session_id = (int) $session_id; $sessionCondition = " session_id = $session_id"; if (empty($session_id)) { - $sessionCondition = " (session_id = 0 OR session_id IS NULL) "; + $sessionCondition = ' (session_id = 0 OR session_id IS NULL) '; } // Definition of tables. @@ -4646,7 +4667,7 @@ function api_get_item_property_info($course_id, $tool, $ref, $session_id = 0, $g $sessionCondition "; if (!empty($groupId)) { - $groupId = intval($groupId); + $groupId = (int) $groupId; $sql .= " AND to_group_id = $groupId "; } @@ -4972,6 +4993,8 @@ function api_get_language_from_type($lang_type) * * @param int $languageId * + * @throws Exception + * * @return array */ function api_get_language_info($languageId) @@ -5962,7 +5985,7 @@ function api_get_access_urls($from = 0, $to = 1000000, $order = 'url', $directio function api_get_access_url($id, $returnDefault = true) { static $staticResult; - $id = intval($id); + $id = (int) $id; if (isset($staticResult[$id])) { $result = $staticResult[$id]; @@ -6410,7 +6433,7 @@ function api_get_current_access_url_id() */ function api_get_access_url_from_user($user_id) { - $user_id = intval($user_id); + $user_id = (int) $user_id; $table_url_rel_user = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER); $table_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL); $sql = "SELECT access_url_id @@ -6705,7 +6728,7 @@ function api_get_tools_lists($my_tool = null) */ function api_check_term_condition($userId) { - if (api_get_setting('allow_terms_conditions') == 'true') { + if (api_get_setting('allow_terms_conditions') === 'true') { // Check if exists terms and conditions if (LegalManager::count() == 0) { return true; @@ -6721,10 +6744,10 @@ function api_check_term_condition($userId) $result = $data['value']; $user_conditions = explode(':', $result); $version = $user_conditions[0]; - $lang_id = $user_conditions[1]; - $real_version = LegalManager::get_last_version($lang_id); + $langId = $user_conditions[1]; + $realVersion = LegalManager::get_last_version($langId); - return $version >= $real_version; + return $version >= $realVersion; } return false; @@ -7656,8 +7679,8 @@ function api_is_global_chat_enabled() { return !api_is_anonymous() && - api_get_setting('allow_global_chat') == 'true' && - api_get_setting('allow_social_tool') == 'true'; + api_get_setting('allow_global_chat') === 'true' && + api_get_setting('allow_social_tool') === 'true'; } /** @@ -7969,6 +7992,18 @@ function api_set_settings_and_plugins() $_SESSION['_plugins'] = $_plugins; } +/** + * Modify default memory_limit and max_execution_time limits + * Needed when processing long tasks. + */ +function api_set_more_memory_and_time_limits() +{ + if (function_exists('ini_set')) { + api_set_memory_limit('256M'); + ini_set('max_execution_time', 1800); + } +} + /** * Tries to set memory limit, if authorized and new limit is higher than current. * @@ -8447,7 +8482,7 @@ function convert_double_quote_to_single($in_text) */ function api_get_origin() { - $origin = isset($_REQUEST['origin']) ? htmlspecialchars($_REQUEST['origin'], ENT_QUOTES) : ''; + $origin = isset($_REQUEST['origin']) ? Security::remove_XSS($_REQUEST['origin']) : ''; return $origin; } @@ -8589,7 +8624,7 @@ function api_is_student_boss() function api_is_excluded_user_type($checkDB = false, $userId = 0) { if ($checkDB) { - $userId = empty($userId) ? api_get_user_id() : intval($userId); + $userId = empty($userId) ? api_get_user_id() : (int) $userId; if ($userId == 0) { return true; @@ -8881,12 +8916,10 @@ function api_mail_html( // Attachment ... if (!empty($data_file)) { - $o = 0; foreach ($data_file as $file_attach) { if (!empty($file_attach['path']) && !empty($file_attach['filename'])) { $mail->AddAttachment($file_attach['path'], $file_attach['filename']); } - $o++; } } @@ -9038,7 +9071,7 @@ function api_unique_multidim_array($array, $key) } /** - * Limit the access to Session Admins wheen the limit_session_admin_role + * Limit the access to Session Admins when the limit_session_admin_role * configuration variable is set to true. */ function api_protect_limit_for_session_admin() @@ -9086,8 +9119,8 @@ function api_upload_file($type, $file, $itemId, $cropParameters = '') } $pathToSave = $path.$name; + $result = moveUploadedFile($file, $pathToSave); - $result = move_uploaded_file($file['tmp_name'], $pathToSave); if ($result) { if (!empty($cropParameters)) { $image = new Image($pathToSave); @@ -9170,6 +9203,26 @@ function api_remove_uploaded_file($type, $file) } } +/** + * @param string $type + * @param int $itemId + * @param string $file + * + * @return bool + */ +function api_remove_uploaded_file_by_id($type, $itemId, $file) +{ + $file = api_get_uploaded_file($type, $itemId, $file, false); + $typePath = api_get_path(SYS_UPLOAD_PATH).$type; + if (Security::check_abs_path($file, $typePath) && file_exists($file) && is_file($file)) { + unlink($file); + + return true; + } + + return false; +} + /** * Converts string value to float value. * @@ -9230,9 +9283,49 @@ function location($url, $exit = true) */ function api_get_web_url() { - if (api_get_setting('server_type') == 'test') { + if (api_get_setting('server_type') === 'test') { return api_get_path(WEB_PATH).'web/app_dev.php/'; } else { return api_get_path(WEB_PATH).'web/'; } } + +/** + * @param string $from + * @param string $to + * + * @return string + */ +function api_get_relative_path($from, $to) +{ + // some compatibility fixes for Windows paths + $from = is_dir($from) ? rtrim($from, '\/').'/' : $from; + $to = is_dir($to) ? rtrim($to, '\/').'/' : $to; + $from = str_replace('\\', '/', $from); + $to = str_replace('\\', '/', $to); + + $from = explode('/', $from); + $to = explode('/', $to); + $relPath = $to; + + foreach ($from as $depth => $dir) { + // find first non-matching dir + if ($dir === $to[$depth]) { + // ignore this directory + array_shift($relPath); + } else { + // get number of remaining dirs to $from + $remaining = count($from) - $depth; + if ($remaining > 1) { + // add traversals up to first matching dir + $padLength = (count($relPath) + $remaining - 1) * -1; + $relPath = array_pad($relPath, $padLength, '..'); + break; + } else { + $relPath[0] = './'.$relPath[0]; + } + } + } + + return implode('/', $relPath); +} diff --git a/main/inc/lib/banner.lib.php b/main/inc/lib/banner.lib.php index eaf8e4e3f5..a86e62d1f3 100755 --- a/main/inc/lib/banner.lib.php +++ b/main/inc/lib/banner.lib.php @@ -200,6 +200,26 @@ function return_logo($theme = '') ); } +/** + * Check if user have access to "who is online" page. + * + * @return bool + */ +function accessToWhoIsOnline() +{ + $user_id = api_get_user_id(); + $course_id = api_get_course_int_id(); + $access = false; + if ((api_get_setting('showonline', 'world') == 'true' && !$user_id) || + (api_get_setting('showonline', 'users') == 'true' && $user_id) || + (api_get_setting('showonline', 'course') == 'true' && $user_id && $course_id) + ) { + $access = true; + } + + return $access; +} + /** * Return HTML string of a list as
  • items. * @@ -208,19 +228,11 @@ function return_logo($theme = '') function returnNotificationMenu() { $courseInfo = api_get_course_info(); - $course_id = 0; - if (!empty($courseInfo)) { - $course_id = $courseInfo['code']; - } - $user_id = api_get_user_id(); $sessionId = api_get_session_id(); $html = ''; - if ((api_get_setting('showonline', 'world') == 'true' && !$user_id) || - (api_get_setting('showonline', 'users') == 'true' && $user_id) || - (api_get_setting('showonline', 'course') == 'true' && $user_id && $course_id) - ) { + if (accessToWhoIsOnline()) { $number = getOnlineUsersCount(); $number_online_in_course = getOnlineUsersInCourseCount($user_id, $courseInfo); diff --git a/main/inc/lib/certificate.lib.php b/main/inc/lib/certificate.lib.php index c9d7fc1b44..a89b7c09bc 100755 --- a/main/inc/lib/certificate.lib.php +++ b/main/inc/lib/certificate.lib.php @@ -152,12 +152,12 @@ class Certificate extends Model if (!empty($path_info) && isset($path_info)) { $this->certification_user_path = $path_info.'certificate/'; $this->certification_web_user_path = $web_path_info.'certificate/'; - + $mode = api_get_permissions_for_new_directories(); if (!is_dir($path_info)) { - mkdir($path_info, 0777, true); + mkdir($path_info, $mode, true); } if (!is_dir($this->certification_user_path)) { - mkdir($this->certification_user_path, 0777); + mkdir($this->certification_user_path, $mode); } } } @@ -645,8 +645,8 @@ class Certificate extends Model // Remove media=screen to be available when printing a document $certificateContent = str_replace( - api_get_path(WEB_CSS_PATH).'editor.css" media="screen"', - api_get_path(WEB_CSS_PATH).'editor.css" ', + ' media="screen"', + '', $certificateContent ); @@ -700,16 +700,19 @@ class Certificate extends Model } $sessions = SessionManager::get_sessions_by_user($this->user_id, false, true); + $totalTimeInLearningPaths = 0; $sessionsApproved = []; + $coursesApproved = []; if ($sessions) { foreach ($sessions as $session) { $allCoursesApproved = []; foreach ($session['courses'] as $course) { $courseInfo = api_get_course_info_by_id($course['real_id']); + $courseCode = $courseInfo['code']; $gradebookCategories = Category::load( null, null, - $courseInfo['code'], + $courseCode, null, false, $session['session_id'] @@ -725,6 +728,16 @@ class Certificate extends Model ); if ($result) { + $coursesApproved[$course['real_id']] = $courseInfo['title']; + + // Find time spent in LP + $totalTimeInLearningPaths += Tracking::get_time_spent_in_lp( + $this->user_id, + $courseCode, + [], + $session['session_id'] + ); + $allCoursesApproved[] = true; } } @@ -780,7 +793,8 @@ class Certificate extends Model ); $tplContent->assign('skills', $skills); $tplContent->assign('sessions', $sessionsApproved); - + $tplContent->assign('courses', $coursesApproved); + $tplContent->assign('time_spent_in_lps', api_time_to_hms($totalTimeInLearningPaths)); $layoutContent = $tplContent->get_template('gradebook/custom_certificate.tpl'); $content = $tplContent->fetch($layoutContent); diff --git a/main/inc/lib/course.lib.php b/main/inc/lib/course.lib.php index a7a2f16f23..e23af49b1b 100755 --- a/main/inc/lib/course.lib.php +++ b/main/inc/lib/course.lib.php @@ -608,13 +608,12 @@ class CourseManager return false; //detected possible SQL injection } - $course_code = Database::escape_string($course_code); $courseInfo = api_get_course_info($course_code); $courseId = $courseInfo['real_id']; $courseCode = $courseInfo['code']; $userCourseCategoryId = intval($userCourseCategoryId); - if (empty($user_id) || empty($course_code)) { + if (empty($user_id) || empty($courseCode)) { return false; } @@ -657,7 +656,7 @@ class CourseManager Event::addEvent( LOG_SUBSCRIBE_USER_TO_COURSE, LOG_COURSE_CODE, - $course_code, + $courseCode, api_get_utc_datetime(), api_get_user_id(), $courseId, @@ -685,7 +684,7 @@ class CourseManager Event::addEvent( LOG_SUBSCRIBE_USER_TO_COURSE, LOG_COURSE_CODE, - $course_code, + $courseCode, api_get_utc_datetime(), api_get_user_id(), $courseId @@ -772,11 +771,11 @@ class CourseManager * @author Hugues Peeters * @author Roan Embrechts * - * @param int $user_id the id of the user - * @param string $courseCode the course code - * @param int $status (optional) The user's status in the course - * @param int $userCourseCategoryId - * @param int The user category in which this subscription will be classified + * @param int $user_id the id of the user + * @param string $courseCode the course code + * @param int $status (optional) The user's status in the course + * @param int $userCourseCategoryId The user category in which this subscription will be classified + * @param bool $checkTeacherPermission * * @return false|string true if subscription succeeds, boolean false otherwise * @assert ('', '') === false @@ -785,7 +784,8 @@ class CourseManager $user_id, $courseCode, $status = STUDENT, - $userCourseCategoryId = 0 + $userCourseCategoryId = 0, + $checkTeacherPermission = true ) { $debug = false; $user_table = Database::get_main_table(TABLE_MAIN_USER); @@ -825,7 +825,7 @@ class CourseManager return false; // The user has been subscribed to the course. } - if (!api_is_course_admin()) { + if ($checkTeacherPermission && !api_is_course_admin()) { // Check in advance whether subscription is allowed or not for this course. $sql = "SELECT code, visibility FROM $course_table WHERE id = $courseId AND subscribe = '".SUBSCRIBE_NOT_ALLOWED."'"; @@ -1281,6 +1281,7 @@ class CourseManager * @param array $userIdList * @param string $filterByActive * @param array $sessionIdList + * @param string $searchByKeyword * * @return array|int */ @@ -1297,12 +1298,13 @@ class CourseManager $courseCodeList = [], $userIdList = [], $filterByActive = null, - $sessionIdList = [] + $sessionIdList = [], + $searchByKeyword = '' ) { $course_table = Database::get_main_table(TABLE_MAIN_COURSE); $sessionTable = Database::get_main_table(TABLE_MAIN_SESSION); - $session_id = intval($session_id); + $session_id = (int) $session_id; $course_code = Database::escape_string($course_code); $courseInfo = api_get_course_info($course_code); $courseId = 0; @@ -1399,12 +1401,13 @@ class CourseManager } } - $sql .= ' FROM '.Database::get_main_table(TABLE_MAIN_USER).' as user ' - .' LEFT JOIN '.Database::get_main_table(TABLE_MAIN_COURSE_USER).' as course_rel_user + $sql .= " FROM ".Database::get_main_table(TABLE_MAIN_USER)." as user + LEFT JOIN ".Database::get_main_table(TABLE_MAIN_COURSE_USER)." as course_rel_user ON user.id = course_rel_user.user_id AND - course_rel_user.relation_type <> '.COURSE_RELATION_TYPE_RRHH.' ' - ." INNER JOIN $course_table course ON course_rel_user.c_id = course.id "; + course_rel_user.relation_type <> ".COURSE_RELATION_TYPE_RRHH." + INNER JOIN $course_table course + ON course_rel_user.c_id = course.id "; if (!empty($course_code)) { $sql .= ' AND course_rel_user.c_id = "'.$courseId.'"'; @@ -1412,7 +1415,7 @@ class CourseManager $where[] = ' course_rel_user.c_id IS NOT NULL '; if (isset($filter_by_status) && is_numeric($filter_by_status)) { - $filter_by_status = intval($filter_by_status); + $filter_by_status = (int) $filter_by_status; $filter_by_status_condition = " course_rel_user.status = $filter_by_status AND "; } } @@ -1465,10 +1468,19 @@ class CourseManager } if (isset($filterByActive)) { - $filterByActive = intval($filterByActive); + $filterByActive = (int) $filterByActive; $sql .= ' AND user.active = '.$filterByActive; } + if (!empty($searchByKeyword)) { + $searchByKeyword = Database::escape_string($searchByKeyword); + $sql .= " AND ( + user.firstname LIKE '$searchByKeyword' OR + user.username LIKE '$searchByKeyword' OR + user.lastname LIKE '$searchByKeyword' + ) "; + } + $sql .= ' '.$order_by.' '.$limit; $rs = Database::query($sql); @@ -2302,6 +2314,8 @@ class CourseManager rename($course_dir, $archive_dir); } + Category::deleteFromCourse($course['code']); + // Unsubscribe all users from the course $sql = "DELETE FROM $table_course_user WHERE c_id = $courseId"; Database::query($sql); @@ -2372,8 +2386,10 @@ class CourseManager WHERE course_id = $courseId"; Database::query($sql); - $sql = "DELETE FROM skill_rel_course WHERE c_id = $courseId"; - Database::query($sql); + if (api_get_configuration_value('allow_skill_rel_items')) { + $sql = "DELETE FROM skill_rel_course WHERE c_id = $courseId"; + Database::query($sql); + } // Deletes all groups, group-users, group-tutors information // To prevent fK mix up on some tables @@ -4305,7 +4321,7 @@ class CourseManager $course_info = api_get_course_info_by_id($course['real_id']); $course_visibility = $course_info['visibility']; - if ($course_visibility == COURSE_VISIBILITY_HIDDEN) { + if ($course_visibility === COURSE_VISIBILITY_HIDDEN) { return ''; } @@ -4360,9 +4376,10 @@ class CourseManager $sessionCourseAvailable = true; } - if ($userInCourseStatus == COURSEMANAGER || $sessionCourseAvailable) { + if ($userInCourseStatus === COURSEMANAGER || $sessionCourseAvailable) { $session_url = $course_info['course_public_url'].'?id_session='.$course_info['id_session']; - $session_title = ''.$course_info['name'].''.$notifications; + $session_title = ''. + $course_info['name'].''.$notifications; } else { $session_title = $course_info['name']; } @@ -4397,6 +4414,7 @@ class CourseManager $params['image'] = $image; $params['link'] = $session_url; $params['title'] = $session_title; + $params['name'] = $course_info['name']; $params['edit_actions'] = ''; $params['document'] = ''; $params['category'] = $course_info['categoryName']; @@ -4407,7 +4425,10 @@ class CourseManager if (api_is_platform_admin()) { $params['edit_actions'] .= api_get_path(WEB_CODE_PATH).'course_info/infocours.php?cidReq='.$course_info['code']; if ($load_dirs) { - $params['document'] .= ''. + $params['document'] .= ''. Display::returnFontAwesomeIcon('folder-open').''; $params['document'] .= Display::div('', [ 'id' => 'document_result_'.$course_info['real_id'].'_'.$course_info['id_session'], @@ -4421,7 +4442,6 @@ class CourseManager $course_info['real_id'], true ); - $course_coachs = self::get_coachs_from_course( $course_info['id_session'], $course_info['real_id'] @@ -4437,7 +4457,9 @@ class CourseManager $special = isset($course['special_course']) ? true : false; $params['title'] = $session_title; $params['special'] = $special; - $params['code'] = $course_info['visual_code']; + if (api_get_setting('display_coursecode_in_courselist') === 'true') { + $params['visual_code'] = '('.$course_info['visual_code'].')'; + } $params['extra'] = ''; $html = $params; @@ -4456,8 +4478,8 @@ class CourseManager $session_category_id = self::get_session_category_id_by_session_id($course_info['id_session']); if ( - $session['access_start_date'] == '0000-00-00 00:00:00' || empty($session['access_start_date']) || - $session['access_start_date'] == '0000-00-00' + $session['access_start_date'] === '0000-00-00 00:00:00' || empty($session['access_start_date']) || + $session['access_start_date'] === '0000-00-00' ) { $session['dates'] = ''; if (api_get_setting('show_session_coach') === 'true') { @@ -4465,7 +4487,9 @@ class CourseManager } $active = true; } else { - $session['dates'] = ' - '.get_lang('From').' '.$session['access_start_date'].' '.get_lang('To').' '.$session['access_end_date']; + $session['dates'] = ' - '. + get_lang('From').' '.$session['access_start_date'].' '. + get_lang('To').' '.$session['access_end_date']; if (api_get_setting('show_session_coach') === 'true') { $session['coach'] = get_lang('GeneralCoach').': '.$sessionCoachName; } @@ -5587,6 +5611,7 @@ class CourseManager 'enable_forum_auto_launch', 'show_course_in_user_language', 'email_to_teachers_on_new_work_feedback', + 'student_delete_own_publication', ]; $courseModels = ExerciseLib::getScoreModels(); @@ -5991,6 +6016,7 @@ class CourseManager { $userList = self::getCourseUsers(true); $groupList = self::getCourseGroups(); + $array = self::buildSelectOptions( $groupList, $userList, @@ -6648,6 +6674,37 @@ class CourseManager return ''; } + /** + * @param Course $course + * + * @return bool + */ + public static function hasPicture(Course $course) + { + return file_exists(api_get_path(SYS_COURSE_PATH).$course->getDirectory().'/course-pic85x85.png'); + } + + /** + * Get the course picture path. + * + * @param Course $course + * @param bool $fullSize + * + * @return null|string + */ + public static function getPicturePath(Course $course, $fullSize = false) + { + if (!self::hasPicture($course)) { + return null; + } + + if ($fullSize) { + return api_get_path(WEB_COURSE_PATH).$course->getDirectory().'/course-pic.png'; + } + + return api_get_path(WEB_COURSE_PATH).$course->getDirectory().'/course-pic85x85.png'; + } + /** * @param ToolChain $toolList */ diff --git a/main/inc/lib/course_description.lib.php b/main/inc/lib/course_description.lib.php index 1c5483a615..43f5f05096 100755 --- a/main/inc/lib/course_description.lib.php +++ b/main/inc/lib/course_description.lib.php @@ -84,7 +84,7 @@ class CourseDescription true, true ); - $course_id = api_get_course_int_id(); + $course_id = $this->course_id ?: api_get_course_int_id(); $sql = "SELECT * FROM $table WHERE c_id = $course_id $condition_session ORDER BY id "; diff --git a/main/inc/lib/course_home.lib.php b/main/inc/lib/course_home.lib.php index 258968b430..aee9c540da 100755 --- a/main/inc/lib/course_home.lib.php +++ b/main/inc/lib/course_home.lib.php @@ -132,10 +132,10 @@ class CourseHome foreach ($all_tools as &$tool) { if ($tool['image'] == 'scormbuilder.gif') { // check if the published learnpath is visible for student - $published_lp_id = self::get_published_lp_id_from_link($tool['link']); + $lpId = self::getPublishedLpIdFromLink($tool['link']); if (!api_is_allowed_to_edit(null, true) && !learnpath::is_lp_visible_for_student( - $published_lp_id, + $lpId, api_get_user_id(), api_get_course_id(), api_get_session_id() @@ -338,11 +338,11 @@ class CourseHome foreach ($all_tools_list as &$tool) { if ($tool['image'] == 'scormbuilder.gif') { // check if the published learnpath is visible for student - $published_lp_id = self::get_published_lp_id_from_link($tool['link']); + $lpId = self::getPublishedLpIdFromLink($tool['link']); if (!api_is_allowed_to_edit(null, true) && !learnpath::is_lp_visible_for_student( - $published_lp_id, + $lpId, api_get_user_id(), api_get_course_id(), api_get_session_id() @@ -644,34 +644,35 @@ class CourseHome } } - if ($temp_row['image'] == 'scormbuilder.gif') { - $lp_id = self::get_published_lp_id_from_link($temp_row['link']); - $lp = new learnpath( - api_get_course_id(), - $lp_id, - $userId - ); - $path = $lp->get_preview_image_path(ICON_SIZE_BIG); - - $add = learnpath::is_lp_visible_for_student( - $lp_id, - $userId, - api_get_course_id(), - api_get_session_id() - ); - if ($path) { - $temp_row['custom_image'] = $path; - } - } + switch ($temp_row['image']) { + case 'scormbuilder.gif': + $lpId = self::getPublishedLpIdFromLink($temp_row['link']); + $lp = new learnpath( + api_get_course_id(), + $lpId, + $userId + ); + $path = $lp->get_preview_image_path(ICON_SIZE_BIG); - if ($temp_row['image'] === 'lp_category.gif') { - $lpCategory = self::getPublishedLpCategoryFromLink( - $temp_row['link'] - ); - $add = learnpath::categoryIsVisibleForStudent( - $lpCategory, - $user - ); + $add = learnpath::is_lp_visible_for_student( + $lpId, + $userId, + api_get_course_id(), + api_get_session_id() + ); + if ($path) { + $temp_row['custom_image'] = $path; + } + break; + case 'lp_category.gif': + $lpCategory = self::getPublishedLpCategoryFromLink( + $temp_row['link'] + ); + $add = learnpath::categoryIsVisibleForStudent( + $lpCategory, + $user + ); + break; } if ($add) { @@ -839,13 +840,13 @@ class CourseHome $tool['original_link'] = $tool['link']; if ($tool['image'] == 'scormbuilder.gif') { // check if the published learnpath is visible for student - $published_lp_id = self::get_published_lp_id_from_link($tool['link']); + $lpId = self::getPublishedLpIdFromLink($tool['link']); if (api_is_allowed_to_edit(null, true)) { $studentview = true; } if (!api_is_allowed_to_edit(null, true) && !learnpath::is_lp_visible_for_student( - $published_lp_id, + $lpId, api_get_user_id(), api_get_course_id(), api_get_session_id() @@ -1197,18 +1198,18 @@ class CourseHome * * @return int Learning path id */ - public static function get_published_lp_id_from_link($published_lp_link) + public static function getPublishedLpIdFromLink($link) { - $lp_id = 0; - $param_lp_id = strstr($published_lp_link, 'lp_id='); - if (!empty($param_lp_id)) { - $a_param_lp_id = explode('=', $param_lp_id); - if (isset($a_param_lp_id[1])) { - $lp_id = intval($a_param_lp_id[1]); + $lpId = 0; + $param = strstr($link, 'lp_id='); + if (!empty($param)) { + $paramList = explode('=', $param); + if (isset($paramList[1])) { + $lpId = (int) $paramList[1]; } } - return $lp_id; + return $lpId; } /** diff --git a/main/inc/lib/database.constants.inc.php b/main/inc/lib/database.constants.inc.php index 657b016b0e..d92028ecda 100755 --- a/main/inc/lib/database.constants.inc.php +++ b/main/inc/lib/database.constants.inc.php @@ -344,3 +344,6 @@ define('TABLE_CAL_DATE', 'cal_dates'); define('TABLE_CAL_HORAIRE', 'cal_horaire'); define('TABLE_CAL_TEMP', 'cal_temp'); define('TABLE_STATISTIC_TRACK_E_EXERCICES_TEMP', 'track_e_exercices_temp'); + +define('TABLE_USER_INFO_DEF', 'userinfo_def'); +define('TABLE_USER_INFO_CONTENT', 'userinfo_content'); diff --git a/main/inc/lib/diagnoser.lib.php b/main/inc/lib/diagnoser.lib.php index b401de1eb7..9116fcbc69 100755 --- a/main/inc/lib/diagnoser.lib.php +++ b/main/inc/lib/diagnoser.lib.php @@ -203,7 +203,12 @@ class Diagnoser $dir = api_get_path(SYS_PATH); $du = exec('du -sh '.$dir, $err); list($size, $none) = explode("\t", $du); - $limit = $_configuration[$access_url_id]['hosting_limit_disk_space']; + $limit = 0; + if (isset($_configuration[$access_url_id])) { + if (isset($_configuration[$access_url_id]['hosting_limit_disk_space'])) { + $limit = $_configuration[$access_url_id]['hosting_limit_disk_space']; + } + } $message2 .= sprintf(get_lang('TotalSpaceUsedByPortalXLimitIsYMB'), $size, $limit); } } diff --git a/main/inc/lib/document.lib.php b/main/inc/lib/document.lib.php index a2fdcf8962..a33b309d2c 100644 --- a/main/inc/lib/document.lib.php +++ b/main/inc/lib/document.lib.php @@ -139,7 +139,7 @@ class DocumentManager 'movie' => 'video/x-sgi-movie', 'mp2' => 'audio/mpeg', 'mp3' => 'audio/mpeg', - 'mp4' => 'video/mpeg4-generic', + 'mp4' => 'video/mp4', 'mpa' => 'audio/mpeg', 'mpe' => 'video/mpeg', 'mpeg' => 'video/mpeg', @@ -263,7 +263,7 @@ class DocumentManager //$filename will be an array if a . was found if (is_array($extension)) { - $extension = strtolower($extension[sizeof($extension) - 1]); + $extension = strtolower($extension[count($extension) - 1]); } else { //file without extension $extension = 'empty'; @@ -273,6 +273,7 @@ class DocumentManager if (isset($mime_types[$extension])) { return $mime_types[$extension]; } + //else return octet-stream return 'application/octet-stream'; } @@ -349,7 +350,9 @@ class DocumentManager // Commented to avoid double caching declaration when playing with IE and HTTPS //header('Cache-Control: no-cache, must-revalidate'); //header('Pragma: no-cache'); + $contentType = self::file_get_mime_type($filename); + switch ($contentType) { case 'text/html': if (isset($lpFixedEncoding) && $lpFixedEncoding === 'true') { @@ -379,11 +382,13 @@ class DocumentManager header('Content-type: '.$contentType); header('Content-Length: '.$len); - $user_agent = strtolower($_SERVER['HTTP_USER_AGENT']); - if (strpos($user_agent, 'msie')) { + $userAgent = strtolower($_SERVER['HTTP_USER_AGENT']); + + if (strpos($userAgent, 'msie')) { header('Content-Disposition: ; filename= '.$filename); } else { - header('Content-Disposition: inline; filename= '.$filename); + //header('Content-Disposition: inline'); + header('Content-Disposition: inline;'); } if ($fixLinksHttpToHttps) { @@ -1294,11 +1299,12 @@ class DocumentManager /** * Gets the document data with a given id. * - * @param int $id Document Id (id field in c_document table) - * @param string $course_code Course code - * @param bool $load_parents load folder parents - * @param int $session_id The session ID, - * 0 if requires context *out of* session, and null to use global context + * @param int $id Document Id (id field in c_document table) + * @param string $course_code Course code + * @param bool $load_parents load folder parents + * @param int $session_id The session ID, + * 0 if requires context *out of* session, and null to use global context + * @param bool $ignoreDeleted * * @return array document content */ @@ -1306,7 +1312,8 @@ class DocumentManager $id, $course_code, $load_parents = false, - $session_id = null + $session_id = null, + $ignoreDeleted = false ) { $course_info = api_get_course_info($course_code); $course_id = $course_info['real_id']; @@ -1315,15 +1322,19 @@ class DocumentManager return false; } - $session_id = empty($session_id) ? api_get_session_id() : intval($session_id); + $session_id = empty($session_id) ? api_get_session_id() : (int) $session_id; $www = api_get_path(WEB_COURSE_PATH).$course_info['path'].'/document'; $TABLE_DOCUMENT = Database::get_course_table(TABLE_DOCUMENT); - $id = intval($id); + $id = (int) $id; $sessionCondition = api_get_session_condition($session_id, true, true); $sql = "SELECT * FROM $TABLE_DOCUMENT WHERE c_id = $course_id $sessionCondition AND id = $id"; + if ($ignoreDeleted) { + $sql .= " AND path NOT LIKE '%_DELETED_%' "; + } + $result = Database::query($sql); if ($result && Database::num_rows($result) == 1) { $row = Database::fetch_array($result, 'ASSOC'); @@ -1848,6 +1859,7 @@ class DocumentManager $user_info = api_get_user_info($user_id); $first_name = $user_info['firstname']; $last_name = $user_info['lastname']; + $username = $user_info['username']; $official_code = $user_info['official_code']; // Teacher information @@ -1883,6 +1895,7 @@ class DocumentManager $info_to_replace_in_content_html = [ $first_name, $last_name, + $username, $organization_name, $portal_name, $teacher_first_name, @@ -1902,6 +1915,7 @@ class DocumentManager $tags = [ '((user_firstname))', '((user_lastname))', + '((user_username))', '((gradebook_institution))', '((gradebook_sitename))', '((teacher_firstname))', @@ -2990,9 +3004,10 @@ class DocumentManager { $TABLE_ITEMPROPERTY = Database::get_course_table(TABLE_ITEM_PROPERTY); $TABLE_DOCUMENT = Database::get_course_table(TABLE_DOCUMENT); - $session_id = intval($session_id); - $group_id = intval($group_id); - $course_id = intval($course_id); + + $session_id = (int) $session_id; + $group_id = (int) $group_id; + $course_id = (int) $course_id; if (!$course_id) { $course_id = api_get_course_int_id(); @@ -3013,9 +3028,9 @@ class DocumentManager INNER JOIN $TABLE_DOCUMENT AS docs ON (docs.id = props.ref AND props.c_id = docs.c_id) WHERE - props.c_id = $course_id AND - docs.c_id = $course_id AND - props.tool = '".TOOL_DOCUMENT."' AND + props.c_id = $course_id AND + docs.c_id = $course_id AND + props.tool = '".TOOL_DOCUMENT."' AND props.visibility <> 2 $group_condition $session_condition @@ -3025,7 +3040,7 @@ class DocumentManager if ($result && Database::num_rows($result) != 0) { $row = Database::fetch_row($result); - return $row[0]; + return (int) $row[0]; } else { return 0; } @@ -3122,7 +3137,12 @@ class DocumentManager }*/ //$type = "video/$extension"; - $html = '