Prechádzať zdrojové kódy

Add calendar for sessions planification - refs BT#15394 #2801

Angel Fernando Quiroz Campos 6 rokov pred
rodič
commit
f25743cb1c

+ 56 - 0
app/Resources/public/css/base.css

@@ -9730,6 +9730,62 @@ ul.dropdown-menu.inner > li > a {
     text-align: center;
 }
 
+.pager .current {
+    display: inline-block;
+    padding: 5px 14px;
+    background-color: #fff;
+    font-weight: bold;
+}
+
+#calendar-session-planification .col-session {
+    max-width: 230px;
+    min-width: 230px;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+    width: 230px;
+}
+#calendar-session-planification .col-week {
+    max-width: 15px;
+    min-width: 15px;
+}
+#calendar-session-planification th.col-week {
+    vertical-align: middle;
+}
+#calendar-session-planification th.col-week span {
+    display: block;
+    font-size: 8px;
+    float: left;
+    padding: 0px;
+    transform: rotate(270deg);
+    transform-origin: center center 0;
+}
+#calendar-session-planification td.col-week {
+    padding: 0px 0px;
+    position: relative;
+    white-space: nowrap;
+}
+#calendar-session-planification td.col-week.in_last_year:before,
+#calendar-session-planification td.col-week.in_next_year:after {
+    bottom: 0px;
+    border: 5px solid transparent;
+    border-bottom: 15px solid #FFF;
+    border-top: 15px solid #FFF;
+    content: " ";
+    position: absolute;
+    top: 0px;
+    width: 5px;
+}
+#calendar-session-planification td.col-week.in_last_year:before {
+    border-left-width: 0;
+    left: 0;
+}
+#calendar-session-planification td.col-week.in_next_year:after {
+    border-right-width: 0;
+    right: -1px;
+}
+#calendar-session-planification td.col-week span {
+}
 
 /* Fix grid with one row and multiples columns. Works for .col-sm-6.col-md-4.col-lg-3 */
 .row.clear-rows-6-4-3 {

+ 7 - 0
main/inc/lib/agenda.lib.php

@@ -3000,6 +3000,13 @@ class Agenda
             }
         }
 
+        if ($this->type == 'personal' && !api_is_anonymous()) {
+            $actionsLeft .= Display::url(
+                Display::return_icon('1day.png', get_lang('ViewSessionsPlanification'), [], ICON_SIZE_MEDIUM),
+                $codePath."calendar/planification.php"
+            );
+        }
+
         if (api_is_platform_admin() ||
             api_is_teacher() ||
             api_is_student_boss() ||

+ 197 - 15
main/inc/lib/usermanager.lib.php

@@ -2999,7 +2999,8 @@ class UserManager
         $user_id,
         $is_time_over = true,
         $ignore_visibility_for_admins = false,
-        $ignoreTimeLimit = false
+        $ignoreTimeLimit = false,
+        $getCount = false
     ) {
         if ($user_id != strval(intval($user_id))) {
             return [];
@@ -3017,20 +3018,27 @@ class UserManager
         // LEFT JOIN is used for session_rel_course_rel_user because an inner
         // join would not catch session-courses where the user is general
         // session coach but which do not have students nor coaches registered
-        $dql = "SELECT DISTINCT
-                    s.id,
-                    s.name,
-                    s.accessStartDate AS access_start_date,
-                    s.accessEndDate AS access_end_date,
-                    s.duration,
-                    sc.id AS session_category_id,
-                    sc.name AS session_category_name,
-                    sc.dateStart AS session_category_date_start,
-                    sc.dateEnd AS session_category_date_end,
-                    s.coachAccessStartDate AS coach_access_start_date,
-                    s.coachAccessEndDate AS coach_access_end_date,
-                    CASE WHEN s.accessEndDate IS NULL THEN 1 ELSE 0 END HIDDEN _isFieldNull
-                    $position
+        $dqlSelect = " COUNT(DISTINCT s.id) ";
+
+        if (!$getCount) {
+            $dqlSelect = " DISTINCT
+                s.id,
+                s.name,
+                s.accessStartDate AS access_start_date,
+                s.accessEndDate AS access_end_date,
+                s.duration,
+                sc.id AS session_category_id,
+                sc.name AS session_category_name,
+                sc.dateStart AS session_category_date_start,
+                sc.dateEnd AS session_category_date_end,
+                s.coachAccessStartDate AS coach_access_start_date,
+                s.coachAccessEndDate AS coach_access_end_date,
+                CASE WHEN s.accessEndDate IS NULL THEN 1 ELSE 0 END HIDDEN _isFieldNull
+                $position
+            ";
+        }
+
+        $dql = "SELECT $dqlSelect
                 FROM ChamiloCoreBundle:Session AS s
                 LEFT JOIN ChamiloCoreBundle:SessionRelCourseRelUser AS scu WITH scu.session = s
                 INNER JOIN ChamiloCoreBundle:AccessUrlRelSession AS url WITH url.sessionId = s.id
@@ -3095,6 +3103,10 @@ class UserManager
             )
         ;
 
+        if ($getCount) {
+            return $dqlStudent->getSingleScalarResult() + $dqlCoach->getSingleScalarResult();
+        }
+
         $sessionDataStudent = $dqlStudent->getResult();
         $sessionDataCoach = $dqlCoach->getResult();
 
@@ -3245,6 +3257,7 @@ class UserManager
                 'courses' => $courseList,
                 'collapsed' => $collapsed,
                 'collapsable_link' => $collapsedAction,
+                'duration' => $row['duration'],
             ];
         }
 
@@ -6557,4 +6570,173 @@ SQL;
 
         return $url;
     }
+
+    /**
+     * @param array $userInfo
+     * @param int   $searchYear
+     *
+     * @throws Exception
+     *
+     * @return array
+     */
+    public static function getSubscribedSessionsByYear(array $userInfo, $searchYear)
+    {
+        $timezone = new DateTimeZone(api_get_timezone());
+
+        if (DRH == $userInfo['status']) {
+            $sessions = SessionManager::get_sessions_followed_by_drh($userInfo['id']);
+
+            $sessions = array_map(
+                function ($sessionInfo) {
+                    $sessionInfo['session_id'] = $sessionInfo['id'];
+                    $sessionInfo['session_name'] = $sessionInfo['name'];
+
+                    return $sessionInfo;
+                },
+                $sessions
+            );
+
+            $sessionsByCategory = ['' => $sessions];
+        } else {
+            $sessionsByCategory = self::get_sessions_by_category($userInfo['id'], false, true, true);
+            $sessionsByCategory = array_column($sessionsByCategory, 'sessions');
+        }
+
+        $sessionsList = [];
+
+        foreach ($sessionsByCategory as $categorySessions) {
+            foreach ($categorySessions as $sessionInfo) {
+                if (!empty($sessionInfo['duration'])) {
+                    $courseAccess = CourseManager::getFirstCourseAccessPerSessionAndUser(
+                        $sessionInfo['session_id'],
+                        $userInfo['id']
+                    );
+
+                    if (empty($courseAccess)) {
+                        continue;
+                    }
+
+                    $firstAcessDate = new DateTime(api_get_local_time($courseAccess['login_course_date']), $timezone);
+                    $lastAccessDate = clone $firstAcessDate;
+                    $lastAccessDate->modify("+{$sessionInfo['duration']} days");
+
+                    $firstAccessYear = (int) $firstAcessDate->format('Y');
+                    $lastAccessYear = (int) $lastAccessDate->format('Y');
+
+                    if ($firstAccessYear <= $searchYear && $lastAccessYear >= $searchYear) {
+                        $sessionsList[$sessionInfo['session_id']] = [
+                            'name' => $sessionInfo['session_name'],
+                            'access_start_date' => $firstAcessDate->format('Y-m-d h:i:s'),
+                            'access_end_date' => $lastAccessDate->format('Y-m-d h:i:s'),
+                        ];
+                    }
+
+                    continue;
+                }
+
+                $accessStartDate = !empty($sessionInfo['access_start_date'])
+                    ? new DateTime(api_get_local_time($sessionInfo['access_start_date']), $timezone)
+                    : null;
+                $accessEndDate = !empty($sessionInfo['access_end_date'])
+                    ? new DateTime(api_get_local_time($sessionInfo['access_end_date']), $timezone)
+                    : null;
+                $accessStartYear = $accessStartDate ? (int) $accessStartDate->format('Y') : 0;
+                $accessEndYear = $accessEndDate ? (int) $accessEndDate->format('Y') : 0;
+
+                $isValid = false;
+
+                if ($accessStartYear && $accessEndYear) {
+                    if ($accessStartYear <= $searchYear && $accessEndYear >= $searchYear) {
+                        $isValid = true;
+                    }
+                }
+
+                if ($accessStartYear && !$accessEndYear) {
+                    if ($accessStartYear == $searchYear) {
+                        $isValid = true;
+                    }
+                }
+
+                if (!$accessStartYear && $accessEndYear) {
+                    if ($accessEndYear == $searchYear) {
+                        $isValid = true;
+                    }
+                }
+
+                if ($isValid) {
+                    $sessionsList[$sessionInfo['session_id']] = [
+                        'name' => $sessionInfo['session_name'],
+                        'access_start_date' => $accessStartDate ? $accessStartDate->format('Y-m-d h:i:s') : null,
+                        'access_end_date' => $accessEndDate ? $accessEndDate->format('Y-m-d h:i:s') : null,
+                    ];
+                }
+            }
+        }
+
+        return $sessionsList;
+    }
+
+    /**
+     * Get sessions info for planification calendar.
+     *
+     * @param array $sessionsList Session list from UserManager::getSubscribedSessionsByYear
+     * @param int   $searchYear
+     *
+     * @throws Exception
+     *
+     * @return array
+     */
+    public static function getSessionsCalendarByYear(array $sessionsList, $searchYear)
+    {
+        $timezone = new DateTimeZone(api_get_timezone());
+        $calendar = [];
+
+        foreach ($sessionsList as $sessionId => $sessionInfo) {
+            $startDate = $sessionInfo['access_start_date']
+                ? new DateTime(api_get_local_time($sessionInfo['access_start_date']), $timezone)
+                : null;
+            $endDate = $sessionInfo['access_end_date']
+                ? new DateTime(api_get_local_time($sessionInfo['access_end_date']), $timezone)
+                : null;
+
+            $startYear = $startDate ? (int) $startDate->format('Y') : 0;
+            $startWeekYear = $startDate ? (int) $startDate->format('o') : 0;
+            $startWeek = $startDate ? (int) $startDate->format('W') : 0;
+            $endYear = $endDate ? (int) $endDate->format('Y') : 0;
+            $endWeekYear = $endDate ? (int) $endDate->format('o') : 0;
+            $endWeek = $endDate ? (int) $endDate->format('W') : 0;
+
+            $start = $startWeekYear < $searchYear ? 0 : $startWeek - 1;
+            $duration = $endWeekYear > $searchYear ? 52 - $start : $endWeek - $start;
+
+            $calendar[] = [
+                'id' => $sessionId,
+                'name' => $sessionInfo['name'],
+                'human_date' => SessionManager::convertSessionDateToString($startDate, $endDate, false, true),
+                'start_in_last_year' => $startYear < $searchYear,
+                'end_in_next_year' => $endYear > $searchYear,
+                'no_start' => !$startWeek,
+                'no_end' => !$endWeek,
+                'start' => $start,
+                'duration' => $duration > 0 ? $duration : 1,
+            ];
+        }
+
+        usort(
+            $calendar,
+            function ($sA, $sB) {
+                if ($sA['start'] == $sB['start']) {
+                    return 0;
+                }
+
+                if ($sA['start'] < $sB['start']) {
+                    return -1;
+                }
+
+                return 1;
+            }
+        );
+
+        return $calendar;
+    }
 }

+ 7 - 0
main/mySpace/session.php

@@ -68,6 +68,13 @@ if (api_is_platform_admin(true, true)) {
         api_get_path(WEB_CODE_PATH).'admin/teachers_time_by_session_report.php'
     );
 
+    if (!api_is_session_admin()) {
+        $menu_items[] = Display::url(
+            Display::return_icon('1day.png', get_lang('ViewSessionsPlanification'), [], ICON_SIZE_MEDIUM),
+            api_get_path(WEB_CODE_PATH)."calendar/planification.php"
+        );
+    }
+
     $actionsLeft = '';
     $nb_menu_items = count($menu_items);
     if ($nb_menu_items > 1) {