From 829d55e6c3430b0d3f3032119876bfad139bac6f Mon Sep 17 00:00:00 2001 From: Julio Montoya Date: Fri, 18 Jun 2021 15:10:26 +0200 Subject: [PATCH] Fix SysAnnouncement, load via json using vue - Remove unused code - Use entities + fix relations careers + promotion - Add welcome announcement during installation - Remove unused tpls - --- assets/vue/pages/Home.vue | 35 +- public/main/admin/system_announcements.php | 54 +- public/main/inc/lib/course.lib.php | 2 +- .../main/inc/lib/system_announcements.lib.php | 568 +----------------- src/CoreBundle/Controller/NewsController.php | 53 +- .../DataFixtures/SysAnnouncementFixtures.php | 15 +- src/CoreBundle/Entity/Career.php | 31 +- src/CoreBundle/Entity/Session.php | 57 +- src/CoreBundle/Entity/SessionRelUser.php | 2 +- src/CoreBundle/Entity/SysAnnouncement.php | 10 + .../Repository/SysAnnouncementRepository.php | 150 ++++- .../Resources/views/News/index.html.twig | 8 - .../Resources/views/News/slider.html.twig | 82 --- .../Resources/views/News/view.html.twig | 24 - src/CoreBundle/Tool/AbstractTool.php | 2 +- src/CoreBundle/Traits/ControllerTrait.php | 12 +- 16 files changed, 300 insertions(+), 805 deletions(-) delete mode 100644 src/CoreBundle/Resources/views/News/index.html.twig delete mode 100644 src/CoreBundle/Resources/views/News/slider.html.twig delete mode 100644 src/CoreBundle/Resources/views/News/view.html.twig diff --git a/assets/vue/pages/Home.vue b/assets/vue/pages/Home.vue index 82a3eb490c..6a9f52cefb 100644 --- a/assets/vue/pages/Home.vue +++ b/assets/vue/pages/Home.vue @@ -1,14 +1,45 @@ \ No newline at end of file diff --git a/public/main/admin/system_announcements.php b/public/main/admin/system_announcements.php index 98429311e4..5cabd2db17 100644 --- a/public/main/admin/system_announcements.php +++ b/public/main/admin/system_announcements.php @@ -109,11 +109,11 @@ switch ($action) { $status = true; } - SystemAnnouncementManager::set_visibility( + /*SystemAnnouncementManager::set_visibility( $_GET['id'], $_GET['person'], $status - ); + );*/ echo Display::return_message(get_lang('Update successful'), 'confirmation'); break; case 'delete': @@ -325,14 +325,6 @@ if ($action_todo) { if ($form->validate()) { $values = $form->getSubmitValues(); - /*$visibilityResult = []; - foreach ($visibleList as $key => $value) { - if (!isset($values[$key])) { - $values[$key] = false; - } - $visibilityResult[$key] = (int) $values[$key]; - }*/ - if ('all' === $values['lang']) { $values['lang'] = null; } @@ -371,10 +363,12 @@ if ($action_todo) { [$values['group']] ); } - Display::addFlash(Display::return_message( - get_lang('Announcement has been added'), - 'confirmation' - )); + Display::addFlash( + Display::return_message( + get_lang('Announcement has been added'), + 'confirmation' + ) + ); } api_location(api_get_self()); @@ -397,7 +391,7 @@ if ($action_todo) { $deletePicture = $values['delete_picture'] ?? ''; if ($deletePicture) { - SystemAnnouncementManager::deleteAnnouncementPicture($values['id']); + //SystemAnnouncementManager::deleteAnnouncementPicture($values['id']); } else { // @todo /*$picture = $_FILES['picture']; @@ -438,27 +432,22 @@ if ($action_todo) { } if ($show_announcement_list) { - $criteria = [ 'url' => api_get_url_entity()]; + $criteria = ['url' => api_get_url_entity()]; $announcements = $repo->findBy($criteria); $announcement_data = []; /** @var SysAnnouncement $announcement */ foreach ($announcements as $announcement) { $row = []; $row[] = $announcement->getId(); - $row[] = Display::return_icon(($announcement->isVisible() ? 'accept.png' : 'exclamation.png'), ($announcement->isVisible() ? get_lang('The announcement is available') : get_lang('The announcement is not available'))); + $row[] = Display::return_icon( + ($announcement->isVisible() ? 'accept.png' : 'exclamation.png'), + ($announcement->isVisible() ? get_lang('The announcement is available') : get_lang( + 'The announcement is not available' + )) + ); $row[] = $announcement->getTitle(); $row[] = api_convert_and_format_date($announcement->getDateStart()); $row[] = api_convert_and_format_date($announcement->getDateEnd()); - - //$data = (array) $announcement; - $roles = []; - /*foreach ($visibleList as $key => $value) { - $value = $data[$key]; - $action = $value ? 'make_invisible' : 'make_visible'; - $row[] = "id."&person=".$key."&action=".$action."\">". - Display::return_icon(($value ? 'eyes.png' : 'eyes-close.png'), get_lang('Show/Hide')).""; - }*/ - $row[] = implode(', ', $announcement->getRoles()); /*$row[] = "id."&person=".SystemAnnouncementManager::VISIBLE_TEACHER."&action=".($announcement->visible_teacher ? 'make_invisible' : 'make_visible')."\">".Display::return_icon(($announcement->visible_teacher ? 'eyes.png' : 'eyes-close.png'), get_lang('Show/Hide')).""; @@ -482,15 +471,8 @@ if ($show_announcement_list) { $table->set_header(3, get_lang('Start')); $table->set_header(4, get_lang('End')); $table->set_header(5, get_lang('Roles')); - - $count = 6; - /*foreach ($visibleList as $key => $title) { - $table->set_header($count, $title); - $count++; - }*/ - - $table->set_header($count++, get_lang('Language')); - $table->set_header($count++, get_lang('Edit'), false, 'width="50px"'); + $table->set_header(6, get_lang('Language')); + $table->set_header(7, get_lang('Edit'), false, 'width="50px"'); $form_actions = []; $form_actions['delete_selected'] = get_lang('Delete'); $table->set_form_actions($form_actions); diff --git a/public/main/inc/lib/course.lib.php b/public/main/inc/lib/course.lib.php index dbd54a2de7..3ca3c3b68a 100644 --- a/public/main/inc/lib/course.lib.php +++ b/public/main/inc/lib/course.lib.php @@ -1149,7 +1149,7 @@ class CourseManager return false; } foreach ($user->getStudentSessions() as $session) { - if ($session->isRelatedToCourse($course)) { + if ($session->hasCourse($course)) { return true; } } diff --git a/public/main/inc/lib/system_announcements.lib.php b/public/main/inc/lib/system_announcements.lib.php index db2b001a3f..2a070875b0 100644 --- a/public/main/inc/lib/system_announcements.lib.php +++ b/public/main/inc/lib/system_announcements.lib.php @@ -3,6 +3,7 @@ /* For licensing terms, see /license.txt */ use Chamilo\CoreBundle\Entity\SysAnnouncement; +use Chamilo\CoreBundle\Entity\User; use Chamilo\CoreBundle\Framework\Container; /** @@ -10,328 +11,6 @@ use Chamilo\CoreBundle\Framework\Container; */ class SystemAnnouncementManager { - public const VISIBLE_GUEST = 'visible_guest'; - public const VISIBLE_STUDENT = 'visible_student'; - public const VISIBLE_TEACHER = 'visible_teacher'; - public const VISIBLE_DRH = 'visible_drh'; - public const VISIBLE_SESSION_ADMIN = 'visible_session_admin'; - public const VISIBLE_STUDENT_BOSS = 'visible_boss'; - - public static function getVisibilityList(): array - { - return [ - self::VISIBLE_TEACHER => get_lang('Trainer'), - self::VISIBLE_STUDENT => get_lang('Learner'), - self::VISIBLE_GUEST => get_lang('Guest'), - self::VISIBLE_DRH => get_lang('Human Resources Manager'), - self::VISIBLE_SESSION_ADMIN => get_lang('Session administrator'), - self::VISIBLE_STUDENT_BOSS => get_lang('Superior (n+1)'), - ]; - } - - /** - * @param string $visibility - * - * @return string - */ - public static function getVisibilityCondition($visibility) - { - $list = self::getVisibilityList(); - $visibilityCondition = " AND ".self::VISIBLE_GUEST." = 1 "; - if (in_array($visibility, array_keys($list))) { - $visibilityCondition = " AND $visibility = 1 "; - } - - return $visibilityCondition; - } - - /** - * Displays all announcements. - * - * @param string $visibility VISIBLE_GUEST, VISIBLE_STUDENT or VISIBLE_TEACHER - * @param int $id The identifier of the announcement to display - */ - public static function display_announcements($visibility, $id = -1) - { - $user_selected_language = api_get_language_isocode(); - $db_table = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS); - $tbl_announcement_group = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS_GROUPS); - $userGroup = new UserGroupModel(); - - $temp_user_groups = $userGroup->get_groups_by_user(api_get_user_id(), 0); - $groups = []; - foreach ($temp_user_groups as $user_group) { - $groups = array_merge($groups, [$user_group['id']]); - $groups = array_merge( - $groups, - $userGroup->get_parent_groups($user_group['id']) - ); - } - - $groups_string = '('.implode($groups, ',').')'; - $now = api_get_utc_datetime(); - $sql = "SELECT *, DATE_FORMAT(date_start,'%d-%m-%Y %h:%i:%s') AS display_date - FROM $db_table - WHERE - (lang='$user_selected_language' OR lang IS NULL) AND - (('$now' BETWEEN date_start AND date_end) OR date_end='0000-00-00') "; - - $sql .= self::getVisibilityCondition($visibility); - - if (count($groups) > 0) { - $sql .= " OR id IN ( - SELECT announcement_id FROM $tbl_announcement_group - WHERE group_id in $groups_string - ) "; - } - $current_access_url_id = 1; - if (api_is_multiple_url_enabled()) { - $current_access_url_id = api_get_current_access_url_id(); - } - $sql .= " AND access_url_id = '$current_access_url_id' "; - $sql .= " ORDER BY date_start DESC LIMIT 0,7"; - - $announcements = Database::query($sql); - if (Database::num_rows($announcements) > 0) { - $url = api_get_self(); - echo '
'; - echo '

'.get_lang('Portal news').'

'; - echo '
'.get_lang('More').'
'; - - while ($announcement = Database::fetch_object($announcements)) { - if ($id != $announcement->id) { - $show_url = 'news_list.php#'.$announcement->id; - $display_date = api_convert_and_format_date($announcement->display_date, DATE_FORMAT_LONG); - echo ' -
- -
'.$display_date.'
-
'; - } else { - echo '
-
' - .$announcement->display_date.' - '. - $announcement->title.' - -
'; - } - echo '
'; - } - echo '
'; - } - } - - /** - * @param string $visibility - * @param int $id - * @param int $start - * @param string $user_id - * - * @return string - */ - public static function displayAllAnnouncements( - $visibility, - $id = -1, - $start = 0, - $user_id = '' - ) { - $user_selected_language = api_get_language_isocode(); - $start = (int) $start; - $userGroup = new UserGroupModel(); - $tbl_announcement_group = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS_GROUPS); - $temp_user_groups = $userGroup->get_groups_by_user(api_get_user_id(), 0); - $groups = []; - foreach ($temp_user_groups as $user_group) { - $groups = array_merge($groups, [$user_group['id']]); - $groups = array_merge($groups, $userGroup->get_parent_groups($user_group['id'])); - } - - // Checks if tables exists to not break platform not updated - $groups_string = '('.implode($groups, ',').')'; - - $table = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS); - $now = api_get_utc_datetime(); - - $sql = "SELECT * FROM $table - WHERE - (lang = '$user_selected_language' OR lang IS NULL) AND - ( '$now' >= date_start AND '$now' <= date_end) "; - - $sql .= self::getVisibilityCondition($visibility); - - if (count($groups) > 0) { - $sql .= " OR id IN ( - SELECT announcement_id FROM $tbl_announcement_group - WHERE group_id in $groups_string - ) "; - } - - if (api_is_multiple_url_enabled()) { - $current_access_url_id = api_get_current_access_url_id(); - $sql .= " AND access_url_id IN ('1', '$current_access_url_id')"; - } - - if (!isset($_GET['start']) || 0 == $_GET['start']) { - $sql .= " ORDER BY date_start DESC LIMIT ".$start.",20"; - } else { - $sql .= " ORDER BY date_start DESC LIMIT ".($start + 1).",20"; - } - $announcements = Database::query($sql); - $content = ''; - if (Database::num_rows($announcements) > 0) { - $content .= '
'; - $content .= '

'.get_lang('Portal news').'

'; - $content .= ''; - $content .= ''; - $content .= ''; - $content .= ''; - $content .= '
'; - $content .= self::display_arrow($user_id); - $content .= '
'; - $content .= ''; - while ($announcement = Database::fetch_object($announcements)) { - $display_date = api_convert_and_format_date($announcement->display_date, DATE_FORMAT_LONG); - $content .= ''; - } - $content .= '
'; - $content .= ' -
-

'.$announcement->title.'

-
'.$display_date.'
-
-
' - .$announcement->content.' -
-

'; - $content .= '
'; - - $content .= ''; - $content .= ''; - $content .= ''; - $content .= ''; - $content .= '
'; - $content .= self::display_arrow($user_id); - $content .= '
'; - $content .= '
'; - } - - return $content; - } - - /** - * @param int $user_id - * - * @return string - */ - public static function display_arrow($user_id) - { - $start = (int) $_GET['start']; - $nb_announcement = self::count_nb_announcement($start, $user_id); - $next = ((int) $_GET['start'] + 19); - $prev = ((int) $_GET['start'] - 19); - $content = ''; - if (!isset($_GET['start']) || 0 == $_GET['start']) { - if ($nb_announcement > 20) { - $content .= ''.get_lang('Next').' >> '; - } - } else { - echo ' << '.get_lang('Prev').''; - if ($nb_announcement > 20) { - $content .= ''.get_lang('Next').' >> '; - } - } - - return $content; - } - - /** - * Update announcements picture. - * - * @param int $announcement_id - * @param string the full system name of the image - * from which course picture will be created - * @param string $cropParameters Optional string that contents "x,y,width,height" of a cropped image format - * - * @return bool Returns the resulting. In case of internal error or negative validation returns FALSE. - */ - public static function update_announcements_picture( - $announcement_id, - $source_file = null, - $cropParameters = null - ) { - if (empty($announcement_id)) { - return false; - } - - // course path - /*$store_path = api_get_path(SYS_UPLOAD_PATH).'announcements'; - - if (!file_exists($store_path)) { - mkdir($store_path); - } - // image name - $announcementPicture = $store_path.'/announcement_'.$announcement_id.'.png'; - $announcementPictureSmall = $store_path.'/announcement_'.$announcement_id.'_100x100.png'; - - if (file_exists($announcementPicture)) { - unlink($announcementPicture); - } - if (file_exists($announcementPictureSmall)) { - unlink($announcementPictureSmall); - } - - //Crop the image to adjust 4:3 ratio - $image = new Image($source_file); - $image->crop($cropParameters); - - $medium = new Image($source_file); - $medium->resize(100); - $medium->send_image($announcementPictureSmall, -1, 'png'); - - $normal = new Image($source_file); - $normal->send_image($announcementPicture, -1, 'png'); - - $result = $normal; - - return $result ? $result : false;*/ - } - - /** - * @param int $start - * @param string $user_id - * - * @return int - */ - public static function count_nb_announcement($start = 0, $user_id = '') - { - $start = intval($start); - $user_selected_language = api_get_language_isocode(); - $db_table = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS); - $sql = 'SELECT id FROM '.$db_table.' - WHERE (lang="'.$user_selected_language.'" OR lang IS NULL) '; - - $visibility = self::getCurrentUserVisibility(); - $sql .= self::getVisibilityCondition($visibility); - - $current_access_url_id = 1; - if (api_is_multiple_url_enabled()) { - $current_access_url_id = api_get_current_access_url_id(); - } - $sql .= " AND access_url_id = '$current_access_url_id' "; - $sql .= 'LIMIT '.$start.', 21'; - $announcements = Database::query($sql); - $i = 0; - while ($rows = Database::fetch_array($announcements)) { - $i++; - } - - return $i; - } - /** * Adds an announcement to the database. * @@ -374,8 +53,6 @@ class SystemAnnouncementManager $a_arrayEH = explode(':', $a_dateE[1]); $date_end_to_compare = array_merge($a_arrayED, $a_arrayEH); - $db_table = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS); - if (!checkdate($date_start_to_compare[1], $date_start_to_compare[2], $date_start_to_compare[0])) { Display::addFlash( Display::return_message(get_lang('Invalid start date was given.'), 'warning') @@ -536,9 +213,8 @@ class SystemAnnouncementManager announcement_id =".intval($announcement_id)." AND ag.group_id = g.id"; $res = Database::query($sql); - $groups = Database::fetch_array($res); - return $groups; + return Database::fetch_array($res); } /** @@ -691,56 +367,7 @@ class SystemAnnouncementManager if (false === $res) { return false; } - self::deleteAnnouncementPicture($id); - - return true; - } - - /** - * Gets an announcement. - * - * @param int $id The identifier of the announcement that should be - * - * @return object Object of class StdClass or the required class, containing the query result row - */ - public static function get_announcement($id) - { - $table = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS); - $id = (int) $id; - $sql = "SELECT * FROM ".$table." WHERE id = ".$id; - $announcement = Database::fetch_object(Database::query($sql)); - - return $announcement; - } - - /** - * Change the visibility of an announcement. - * - * @param int $id - * @param int $user For who should the visibility be changed - * @param bool $visible - * - * @return bool True on success, false on failure - */ - public static function set_visibility($id, $user, $visible) - { - $table = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS); - $id = (int) $id; - $list = array_keys(self::getVisibilityList()); - $user = trim($user); - $visible = (int) $visible; - if (!in_array($user, $list)) { - return false; - } - - $field = $user; - $sql = "UPDATE $table SET ".$field." = '".$visible."' - WHERE id='".$id."'"; - $res = Database::query($sql); - - if (false === $res) { - return false; - } + //self::deleteAnnouncementPicture($id); return true; } @@ -758,7 +385,6 @@ class SystemAnnouncementManager $language = $announcement->getLang(); $content = str_replace(['\r\n', '\n', '\r'], '', $content); - $now = api_get_utc_datetime(); if ($sendEmailTest) { MessageManager::send_message_simple(api_get_user_id(), $title, $content); @@ -830,7 +456,7 @@ class SystemAnnouncementManager $users = $qb->getQuery()->getResult(); $message_sent = false; - /** @var \Chamilo\CoreBundle\Entity\User $user */ + /** @var User $user */ foreach ($users as $user) { MessageManager::send_message_simple($user->getId(), $title, $content); $message_sent = true; @@ -847,126 +473,14 @@ class SystemAnnouncementManager return $message_sent; //true if at least one e-mail was sent } - /** - * Displays announcements as an slideshow. - * - * @param string $visible see self::VISIBLE_* constants - * @param int $id The identifier of the announcement to display - */ - public static function getAnnouncements($visible, $id = null): array - { - $user_selected_language = Database::escape_string(api_get_language_isocode()); - $table = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS); - - $cut_size = 500; - $now = api_get_utc_datetime(); - $sql = "SELECT * FROM $table - WHERE - (lang = '$user_selected_language' OR lang = '') AND - ('$now' >= date_start AND '$now' <= date_end) "; - - $sql .= self::getVisibilityCondition($visible); - - if (isset($id) && !empty($id)) { - $id = (int) $id; - $sql .= " AND id = $id "; - } - - if (api_is_multiple_url_enabled()) { - $current_url_id = api_get_current_access_url_id(); - $sql .= " AND access_url_id IN ('1', '$current_url_id') "; - } - - $checkCareers = true === api_get_configuration_value('allow_careers_in_global_announcements'); - - $userId = api_get_user_id(); - - $promotion = new Promotion(); - $sql .= ' ORDER BY date_start DESC'; - $result = Database::query($sql); - $announcements = []; - if (Database::num_rows($result) > 0) { - while ($announcement = Database::fetch_object($result)) { - if ($checkCareers && !empty($announcement->career_id)) { - $promotionList = []; - if (!empty($announcement->promotion_id)) { - $promotionList[] = $announcement->promotion_id; - } else { - $promotionList = $promotion->get_all_promotions_by_career_id($announcement->career_id); - if (!empty($promotionList)) { - $promotionList = array_column($promotionList, 'id'); - } - } - - $show = false; - foreach ($promotionList as $promotionId) { - $sessionList = SessionManager::get_all_sessions_by_promotion($promotionId); - foreach ($sessionList as $session) { - $sessionId = $session['id']; - // Check student - if (self::VISIBLE_STUDENT === $visible && - SessionManager::isUserSubscribedAsStudent($sessionId, $userId) - ) { - $show = true; - break 2; - } - - if (self::VISIBLE_TEACHER === $visible && - SessionManager::user_is_general_coach($userId, $sessionId) - ) { - $show = true; - break 2; - } - - // Check course coach - $coaches = SessionManager::getCoachesBySession($sessionId); - - if (self::VISIBLE_TEACHER === $visible && in_array($userId, $coaches)) { - $show = true; - break 2; - } - } - } - - if (false === $show) { - continue; - } - } - - $announcementData = [ - 'id' => $announcement->id, - 'title' => $announcement->title, - 'content' => $announcement->content, - 'readMore' => null, - ]; - - if (empty($id)) { - if (api_strlen(strip_tags($announcement->content)) > $cut_size) { - $announcementData['content'] = cut($announcement->content, $cut_size); - $announcementData['readMore'] = true; - } - } - - $announcements[] = $announcementData; - } - } - - if (0 === count($announcements)) { - return []; - } - - return $announcements; - } - /** * Get the HTML code for an announcement. * * @param int $announcementId The announcement ID - * @param string $visibility The announcement visibility */ - public static function getAnnouncement($announcementId, $visibility): array + public static function getAnnouncement($announcementId, ?User $user = null): array { - $selectedUserLanguage = Database::escape_string(api_get_language_isocode()); + $selectedUserLanguage = api_get_language_isocode(); $announcementTable = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS); $now = api_get_utc_datetime(); $announcementId = (int) $announcementId; @@ -996,74 +510,4 @@ class SystemAnnouncementManager return $announcement; } - - /** - * @return string - */ - public static function getCurrentUserVisibility() - { - if (api_is_anonymous()) { - return self::VISIBLE_GUEST; - } - - if (api_is_student_boss()) { - return self::VISIBLE_STUDENT_BOSS; - } - - if (api_is_session_admin()) { - return self::VISIBLE_SESSION_ADMIN; - } - - if (api_is_drh()) { - return self::VISIBLE_DRH; - } - - if (api_is_teacher()) { - return self::VISIBLE_TEACHER; - } else { - return self::VISIBLE_STUDENT; - } - } - - /** - * Deletes the Announcement picture. - * - * @param int $announcementId - */ - public static function deleteAnnouncementPicture($announcementId) - { - /*$store_path = api_get_path(SYS_UPLOAD_PATH).'announcements'; - - // image name - $announcementPicture = $store_path.'/announcement_'.$announcementId.'.png'; - $announcementPictureSmall = $store_path.'/announcement_'.$announcementId.'_100x100.png'; - - if (file_exists($announcementPicture)) { - unlink($announcementPicture); - } - if (file_exists($announcementPictureSmall)) { - unlink($announcementPictureSmall); - }*/ - } - - /** - * get announcement picture. - * - * @param int $announcementId - * - * @return string|null - */ - private static function getPictureAnnouncement($announcementId) - { - /*$store_path = api_get_path(SYS_UPLOAD_PATH).'announcements'; - $announcementPicture = $store_path.'/announcement_'.$announcementId.'.png'; - if (file_exists($announcementPicture)) { - $web_path = api_get_path(WEB_UPLOAD_PATH).'announcements'; - $urlPicture = $web_path.'/announcement_'.$announcementId.'.png'; - - return $urlPicture; - } - - return null;*/ - } } diff --git a/src/CoreBundle/Controller/NewsController.php b/src/CoreBundle/Controller/NewsController.php index 859d3b95d4..e86cf56e11 100644 --- a/src/CoreBundle/Controller/NewsController.php +++ b/src/CoreBundle/Controller/NewsController.php @@ -6,68 +6,45 @@ declare(strict_types=1); namespace Chamilo\CoreBundle\Controller; +use Chamilo\CoreBundle\Repository\SysAnnouncementRepository; use Chamilo\CoreBundle\Traits\ControllerTrait; use Display; +use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; -use SystemAnnouncementManager; /** * Class IndexController * author Julio Montoya . - * - * @Route("/news") */ class NewsController extends BaseController { use ControllerTrait; /** - * @Route("/", name="news_index", methods={"GET"}, options={"expose"=true}) + * @Route("/news/list", name="news_index", methods={"GET"}, options={"expose"=true}) */ - public function indexAction(): Response + public function indexAction(SysAnnouncementRepository $sysAnnouncementRepository): Response { - $toolBar = ''; + /*$toolBar = ''; if ($this->isGranted('ROLE_ADMIN')) { $actionEdit = Display::url( Display::return_icon('edit.png', $this->trans('EditSystemAnnouncement'), [], ICON_SIZE_MEDIUM), api_get_path(WEB_PATH).'main/admin/system_announcements.php' ); $toolBar = Display::toolbarAction('toolbar', [$actionEdit]); - } - - return $this->render( - '@ChamiloCore/News/index.html.twig', - [ - 'toolbar' => $toolBar, - ] - ); - } - - /** - * @Route("/{id}", name="news", methods={"GET", "POST"}, options={"expose"=true}) - */ - public function newsAction(int $id = 0): Response - { - $visibility = SystemAnnouncementManager::getCurrentUserVisibility(); - - if (empty($id)) { - $content = SystemAnnouncementManager::getAnnouncements($visibility); - - return $this->render( - '@ChamiloCore/News/slider.html.twig', - [ - 'announcements' => $content, - ] + }*/ + $user = $this->getUser(); + + $list = []; + if (null !== $user) { + $list = $sysAnnouncementRepository->getAnnouncements( + $this->getUser(), + $this->getAccessUrl(), + $this->getRequest()->getLocale() ); } - $content = SystemAnnouncementManager::getAnnouncement($id, $visibility); - return $this->render( - '@ChamiloCore/News/view.html.twig', - [ - 'announcement' => $content, - ] - ); + return new JsonResponse($list); } } diff --git a/src/CoreBundle/DataFixtures/SysAnnouncementFixtures.php b/src/CoreBundle/DataFixtures/SysAnnouncementFixtures.php index 53bc66b277..5af79220e2 100644 --- a/src/CoreBundle/DataFixtures/SysAnnouncementFixtures.php +++ b/src/CoreBundle/DataFixtures/SysAnnouncementFixtures.php @@ -17,13 +17,22 @@ class SysAnnouncementFixtures extends Fixture { $url = $this->getReference(AccessUserFixtures::ACCESS_URL_REFERENCE); + $content = '

+ +

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore + et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut + aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit + esse cillum dolore eu fugiat nulla pariatur. + '; + $sysAnnouncement = (new SysAnnouncement()) - ->setTitle('Welcome') - ->setContent('Welcome message') - ->addRole('ROLE_USER') + ->setTitle('Welcome to Chamilo!') + ->setContent($content) ->setUrl($url) ->setDateStart(new DateTime()) ->setDateEnd(new DateTime('now +30 days')) + ->addRole('ROLE_ANONYMOUS') ; $manager->persist($sysAnnouncement); $manager->flush(); diff --git a/src/CoreBundle/Entity/Career.php b/src/CoreBundle/Entity/Career.php index 52e1661936..9270617c98 100644 --- a/src/CoreBundle/Entity/Career.php +++ b/src/CoreBundle/Entity/Career.php @@ -6,6 +6,8 @@ declare(strict_types=1); namespace Chamilo\CoreBundle\Entity; +use Doctrine\Common\Collections\ArrayCollection; +use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; use Gedmo\Timestampable\Traits\TimestampableEntity; use Symfony\Component\Validator\Constraints as Assert; @@ -46,9 +48,19 @@ class Career */ protected int $status; + /** + * @var Collection|Promotion[] + * + * @ORM\OneToMany( + * targetEntity="Chamilo\CoreBundle\Entity\Promotion", mappedBy="career", cascade={"persist"} + * ) + */ + protected Collection $promotions; + public function __construct() { $this->status = self::CAREER_STATUS_ACTIVE; + $this->promotions = new ArrayCollection(); } /** @@ -68,12 +80,7 @@ class Career return $this; } - /** - * Get name. - * - * @return string - */ - public function getName() + public function getName(): string { return $this->name; } @@ -101,4 +108,16 @@ class Career { return $this->status; } + + public function getPromotions(): array | ArrayCollection | Collection + { + return $this->promotions; + } + + public function setPromotions(array | ArrayCollection | Collection $promotions): self + { + $this->promotions = $promotions; + + return $this; + } } diff --git a/src/CoreBundle/Entity/Session.php b/src/CoreBundle/Entity/Session.php index 22a3b69054..6b2cd4b709 100644 --- a/src/CoreBundle/Entity/Session.php +++ b/src/CoreBundle/Entity/Session.php @@ -11,13 +11,11 @@ use ApiPlatform\Core\Annotation\ApiResource; use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\OrderFilter; use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\SearchFilter; use ApiPlatform\Core\Serializer\Filter\PropertyFilter; -use Database; use DateTime; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\Common\Collections\Criteria; use Doctrine\ORM\Mapping as ORM; -use Exception; use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; use Symfony\Component\Serializer\Annotation\Groups; use Symfony\Component\Validator\Constraints as Assert; @@ -38,9 +36,6 @@ use Symfony\Component\Validator\Constraints as Assert; * @UniqueEntity("name") */ #[ApiResource( - attributes: [ - 'security' => "is_granted('ROLE_ADMIN')", - ], collectionOperations: [ 'get' => [ 'security' => "is_granted('ROLE_ADMIN')", @@ -57,12 +52,15 @@ use Symfony\Component\Validator\Constraints as Assert; 'security' => "is_granted('ROLE_ADMIN')", ], ], - normalizationContext: [ - 'groups' => ['session:read'], + attributes: [ + 'security' => "is_granted('ROLE_ADMIN')", ], denormalizationContext: [ 'groups' => ['session:write'], ], + normalizationContext: [ + 'groups' => ['session:read'], + ], )] #[ApiFilter(SearchFilter::class, properties: ['name' => 'partial'])] #[ApiFilter(PropertyFilter::class)] @@ -445,19 +443,6 @@ class Session implements ResourceWithAccessUrlInterface return false; } - /** - * Check for existence of a relation (SessionRelCourse) between a course and this session. - * - * @return bool whether the course is related to this session - */ - public function isRelatedToCourse(Course $course): bool - { - return null !== Database::getManager()->getRepository(SessionRelCourse::class)->findOneBy([ - 'session' => $this, - 'course' => $course, - ]); - } - /** * Remove $course. */ @@ -500,10 +485,7 @@ class Session implements ResourceWithAccessUrlInterface return $relation->count() > 0; } - /** - * @return bool - */ - public function hasStudentInCourse(User $user, Course $course) + public function hasStudentInCourse(User $user, Course $course): bool { return $this->hasUserInCourse($user, $course, self::STUDENT); } @@ -535,7 +517,18 @@ class Session implements ResourceWithAccessUrlInterface return $this->getSessionRelCourseRelUsers()->matching($criteria); } - public function getCoursesByUser(User $user, $status = null): Collection + public function getAllUsersFromCourse(int $status): Collection + { + $criteria = Criteria::create() + ->where( + Criteria::expr()->eq('status', $status) + ) + ; + + return $this->getSessionRelCourseRelUsers()->matching($criteria); + } + + public function getSessionRelCourseByUser(User $user, $status = null): Collection { $criteria = Criteria::create() ->where( @@ -559,12 +552,7 @@ class Session implements ResourceWithAccessUrlInterface return $this; } - /** - * Get name. - * - * @return string - */ - public function getName() + public function getName(): string { return $this->name; } @@ -816,11 +804,7 @@ class Session implements ResourceWithAccessUrlInterface */ public function isCurrentlyAccessible(): bool { - try { - $now = new Datetime(); - } catch (Exception $exception) { - return false; - } + $now = new Datetime(); return (null === $this->accessStartDate || $this->accessStartDate < $now) && @@ -865,7 +849,6 @@ class Session implements ResourceWithAccessUrlInterface public function setSessionRelCourseRelUsers(Collection $sessionRelCourseRelUsers): self { $this->sessionRelCourseRelUsers = new ArrayCollection(); - foreach ($sessionRelCourseRelUsers as $item) { $this->addSessionRelCourseRelUser($item); } diff --git a/src/CoreBundle/Entity/SessionRelUser.php b/src/CoreBundle/Entity/SessionRelUser.php index af8efbb619..517ebc50f7 100644 --- a/src/CoreBundle/Entity/SessionRelUser.php +++ b/src/CoreBundle/Entity/SessionRelUser.php @@ -140,7 +140,7 @@ class SessionRelUser public function getCourses() { - return $this->session->getCoursesByUser($this->getUser()); + return $this->session->getSessionRelCourseByUser($this->getUser()); } public function getId(): int diff --git a/src/CoreBundle/Entity/SysAnnouncement.php b/src/CoreBundle/Entity/SysAnnouncement.php index ef90f97c15..4a6bcfbd65 100644 --- a/src/CoreBundle/Entity/SysAnnouncement.php +++ b/src/CoreBundle/Entity/SysAnnouncement.php @@ -316,6 +316,11 @@ class SysAnnouncement return $this; } + public function hasCareer(): bool + { + return null !== $this->career; + } + public function getCareer(): ?Career { return $this->career; @@ -328,6 +333,11 @@ class SysAnnouncement return $this; } + public function hasPromotion(): bool + { + return null !== $this->promotion; + } + public function getPromotion(): ?Promotion { return $this->promotion; diff --git a/src/CoreBundle/Repository/SysAnnouncementRepository.php b/src/CoreBundle/Repository/SysAnnouncementRepository.php index 74478ab212..ada4b39c87 100644 --- a/src/CoreBundle/Repository/SysAnnouncementRepository.php +++ b/src/CoreBundle/Repository/SysAnnouncementRepository.php @@ -6,19 +6,29 @@ declare(strict_types=1); namespace Chamilo\CoreBundle\Repository; +use Chamilo\CoreBundle\Entity\AccessUrl; +use Chamilo\CoreBundle\Entity\Session; +use Chamilo\CoreBundle\Entity\SessionRelUser; use Chamilo\CoreBundle\Entity\SysAnnouncement; +use Chamilo\CoreBundle\Entity\User; +use Datetime; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; +use Doctrine\DBAL\Types\Types; +use Doctrine\ORM\QueryBuilder; use Doctrine\Persistence\ManagerRegistry; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; +use Symfony\Component\Security\Core\Security; class SysAnnouncementRepository extends ServiceEntityRepository { protected ParameterBagInterface $parameterBag; + protected Security $security; - public function __construct(ManagerRegistry $registry, ParameterBagInterface $parameterBag) + public function __construct(ManagerRegistry $registry, ParameterBagInterface $parameterBag, Security $security) { parent::__construct($registry, SysAnnouncement::class); $this->parameterBag = $parameterBag; + $this->security = $security; } public function getVisibilityList() @@ -32,6 +42,139 @@ class SysAnnouncementRepository extends ServiceEntityRepository return $roles; } + public function getAnnouncementsQueryBuilder(string $iso, AccessUrl $url, ?User $user = null): QueryBuilder + { + $qb = $this->createQueryBuilder('s'); + $qb + ->andWhere(' s.lang IS NULL OR s.lang = :iso') + ->andWhere('s.url = :url') + ->setParameters( + ['url' => $url, 'iso' => $iso] + ) + ; + + $this->addDateQueryBuilder($qb); + + if (null !== $user) { + $this->addRoleListQueryBuilder($user->getRoles(), $qb); + } + + $qb->orderBy('s.dateStart', 'DESC'); + + return $qb; + } + + public function getAnnouncements(User $user, AccessUrl $url, string $iso): array + { + $qb = $this->getAnnouncementsQueryBuilder($iso, $url, $user); + + $announcements = $qb->getQuery()->getResult(); + $cutSize = 500; + $list = []; + if (!empty($announcements)) { + /** @var SysAnnouncement $announcement */ + foreach ($announcements as $announcement) { + if ($announcement->hasCareer()) { + $promotionList = []; + if ($announcement->hasPromotion()) { + $promotionList[] = $announcement->getPromotion(); + } else { + $promotionList = $announcement->getCareer()->getPromotions(); + } + + $show = false; + foreach ($promotionList as $promotion) { + $sessionList = $promotion->getSessions(); + foreach ($sessionList as $session) { + $subscription = (new SessionRelUser()) + ->setUser($user) + ->setSession($session) + ->setRelationType(0) + ; + + // Check student + if ($this->security->isGranted('ROLE_STUDENT') && + $session->hasUser($subscription) + //\SessionManager::isUserSubscribedAsStudent($sessionId, $userId) + ) { + $show = true; + + break 2; + } + + if ($this->security->isGranted('ROLE_TEACHER') && + $session->isUserGeneralCoach($user) + //SessionManager::user_is_general_coach($userId, $sessionId) + ) { + $show = true; + + break 2; + } + + // Check course coach + //$coaches = \SessionManager::getCoachesBySession($sessionId); + if ($this->security->isGranted('ROLE_TEACHER') && + $session->getSessionRelCourseByUser($user, Session::COACH)->count() > 0 + ) { + $show = true; + + break 2; + } + } + } + + if (false === $show) { + continue; + } + } + + $announcementData = [ + 'id' => $announcement->getId(), + 'title' => $announcement->getTitle(), + 'content' => $announcement->getContent(), + 'readMore' => null, + ]; + + if (api_strlen(strip_tags($announcement->getContent())) > $cutSize) { + $announcementData['content'] = cut($announcement->getContent(), $cutSize); + $announcementData['readMore'] = true; + } + $list[] = $announcementData; + } + } + + if (0 === \count($list)) { + return []; + } + + return $list; + } + + public function addRoleListQueryBuilder(array $roleList, QueryBuilder $qb = null): QueryBuilder + { + $qb = $this->getOrCreateQueryBuilder($qb, 's'); + if (!empty($roleList)) { + $qb + ->andWhere('s.roles IN (:roles) OR s.roles IN (:anon)') + ->setParameter('roles', $roleList, Types::ARRAY) + ->setParameter('anon', ['ROLE_ANONYMOUS'], Types::ARRAY) + ; + } + + return $qb; + } + + public function addDateQueryBuilder(QueryBuilder $qb = null): QueryBuilder + { + $qb = $this->getOrCreateQueryBuilder($qb, 's'); + $qb + ->andWhere('s.dateStart IS NULL OR s.dateEnd > :now') + ->setParameter('now', new Datetime(), Types::DATETIME_MUTABLE) + ; + + return $qb; + } + public function update(SysAnnouncement $sysAnnouncement, $andFlush = true): void { $this->getEntityManager()->persist($sysAnnouncement); @@ -39,4 +182,9 @@ class SysAnnouncementRepository extends ServiceEntityRepository $this->getEntityManager()->flush(); } } + + protected function getOrCreateQueryBuilder(QueryBuilder $qb = null, string $alias = 's'): QueryBuilder + { + return $qb ?: $this->createQueryBuilder($alias); + } } diff --git a/src/CoreBundle/Resources/views/News/index.html.twig b/src/CoreBundle/Resources/views/News/index.html.twig deleted file mode 100644 index 89898af836..0000000000 --- a/src/CoreBundle/Resources/views/News/index.html.twig +++ /dev/null @@ -1,8 +0,0 @@ -{% extends "@ChamiloCore/Layout/layout_one_col.html.twig" %} - -{% block content %} - {% autoescape false %} - {{ toolbar }} - {{ render(controller('ChamiloCoreBundle:News:news')) }} - {% endautoescape %} -{% endblock %} diff --git a/src/CoreBundle/Resources/views/News/slider.html.twig b/src/CoreBundle/Resources/views/News/slider.html.twig deleted file mode 100644 index ad249f7e47..0000000000 --- a/src/CoreBundle/Resources/views/News/slider.html.twig +++ /dev/null @@ -1,82 +0,0 @@ -{% import '@ChamiloCore/Macros/box.html.twig' as macro %} - -{% autoescape false %} -{% set content %} - {% if is_granted('ROLE_ADMIN') %} - - {% endif %} - {% if announcements %} - - {% else %} - -
-
- -
-

{{ "Accelerate your future. Learn where you want and when you want"|trans }}

-
{{ "Develop your skills with Chamilo 2.0"|trans }}
-
-
-
- -
-
- {% endif %} -{% endset %} - - {{ content }} - -{% endautoescape %} \ No newline at end of file diff --git a/src/CoreBundle/Resources/views/News/view.html.twig b/src/CoreBundle/Resources/views/News/view.html.twig deleted file mode 100644 index fe45cb187c..0000000000 --- a/src/CoreBundle/Resources/views/News/view.html.twig +++ /dev/null @@ -1,24 +0,0 @@ -{% extends "@ChamiloCore/Layout/layout_one_col.html.twig" %} - -{% block content %} - {% autoescape false %} - - - {% if not announcement is empty %} -
- -
- {% else %} - - {% endif %} - {% endautoescape %} -{% endblock %} - - diff --git a/src/CoreBundle/Tool/AbstractTool.php b/src/CoreBundle/Tool/AbstractTool.php index adac15c844..95a8acfc35 100644 --- a/src/CoreBundle/Tool/AbstractTool.php +++ b/src/CoreBundle/Tool/AbstractTool.php @@ -123,7 +123,7 @@ abstract class AbstractTool implements ToolInterface return ucfirst(str_replace('_', ' ', $this->nameToShow)); } - public function setNameToShow(string $nameToShow): AbstractTool + public function setNameToShow(string $nameToShow): self { $this->nameToShow = $nameToShow; diff --git a/src/CoreBundle/Traits/ControllerTrait.php b/src/CoreBundle/Traits/ControllerTrait.php index 50d98f55bf..70909d7932 100644 --- a/src/CoreBundle/Traits/ControllerTrait.php +++ b/src/CoreBundle/Traits/ControllerTrait.php @@ -7,6 +7,7 @@ declare(strict_types=1); namespace Chamilo\CoreBundle\Traits; use Chamilo\CoreBundle\Component\Utils\Glide; +use Chamilo\CoreBundle\Entity\AccessUrl; use Chamilo\CoreBundle\Repository\Node\IllustrationRepository; use Chamilo\CoreBundle\Repository\Node\MessageAttachmentRepository; use Chamilo\CoreBundle\Repository\ResourceFactory; @@ -103,10 +104,8 @@ trait ControllerTrait /** * Translator shortcut. - * - * @return string */ - public function trans(string $variable) + public function trans(string $variable): string { /** @var TranslatorInterface $translator */ $translator = $this->container->get('translator'); @@ -122,6 +121,13 @@ trait ControllerTrait return $this->container->get('glide'); } + public function getAccessUrl(): ?AccessUrl + { + $urlId = $this->getRequest()->getSession()->get('access_url_id'); + + return $this->getDoctrine()->getRepository(AccessUrl::class)->find($urlId); + } + /** * @return SettingsManager */