Fix SysAnnouncement, load via json using vue

- Remove unused code
- Use entities + fix relations careers + promotion
- Add welcome announcement during installation
- Remove unused tpls
-
pull/3924/head
Julio Montoya 4 years ago
parent 597a0bdcb4
commit 829d55e6c3
  1. 35
      assets/vue/pages/Home.vue
  2. 50
      public/main/admin/system_announcements.php
  3. 2
      public/main/inc/lib/course.lib.php
  4. 568
      public/main/inc/lib/system_announcements.lib.php
  5. 53
      src/CoreBundle/Controller/NewsController.php
  6. 15
      src/CoreBundle/DataFixtures/SysAnnouncementFixtures.php
  7. 31
      src/CoreBundle/Entity/Career.php
  8. 55
      src/CoreBundle/Entity/Session.php
  9. 2
      src/CoreBundle/Entity/SessionRelUser.php
  10. 10
      src/CoreBundle/Entity/SysAnnouncement.php
  11. 150
      src/CoreBundle/Repository/SysAnnouncementRepository.php
  12. 8
      src/CoreBundle/Resources/views/News/index.html.twig
  13. 82
      src/CoreBundle/Resources/views/News/slider.html.twig
  14. 24
      src/CoreBundle/Resources/views/News/view.html.twig
  15. 2
      src/CoreBundle/Tool/AbstractTool.php
  16. 12
      src/CoreBundle/Traits/ControllerTrait.php

@ -1,14 +1,45 @@
<template>
<q-page class="q-layout-padding">
<div class="flex justify-center lg:mt-16">
<img src="/img/document/images/mr_chamilo/svg/collaborative.svg" />
<div class="flex justify-center">
<div
v-for="announcement in announcements"
:key="announcement.id"
>
<h4>{{ announcement.title }}</h4>
<p v-html="announcement.content" ></p>
</div>
</div>
</q-page>
</template>
<script>
import {useRouter} from "vue-router";
import {useStore} from "vuex";
import axios from "axios";
import {reactive, toRefs} from 'vue'
import {mapGetters} from "vuex";
export default {
name: "Home",
setup() {
const router = useRouter();
const store = useStore();
const state = reactive({
announcements: [],
});
axios.get('/news/list').then(response => {
console.log(response.data);
console.log(response);
if (Array.isArray(response.data)) {
state.announcements = response.data;
}
}).catch(function (error) {
console.log(error);
});
return toRefs(state);
}
}
</script>

@ -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(
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[] = "<a href=\"?id=".$announcement->id."&person=".$key."&action=".$action."\">".
Display::return_icon(($value ? 'eyes.png' : 'eyes-close.png'), get_lang('Show/Hide'))."</a>";
}*/
$row[] = implode(', ', $announcement->getRoles());
/*$row[] = "<a href=\"?id=".$announcement->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'))."</a>";
@ -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);

@ -1149,7 +1149,7 @@ class CourseManager
return false;
}
foreach ($user->getStudentSessions() as $session) {
if ($session->isRelatedToCourse($course)) {
if ($session->hasCourse($course)) {
return true;
}
}

@ -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 '<div class="system_announcements">';
echo '<h3>'.get_lang('Portal news').'</h3>';
echo '<div style="margin:10px;text-align:right;"><a href="news_list.php">'.get_lang('More').'</a></div>';
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 '<a name="'.$announcement->id.'"></a>
<div class="system_announcement">
<div class="system_announcement_title">
<a name="ann'.$announcement->id.'" href="'.$show_url.'">'.
$announcement->title.'</a>
</div>
<div class="system_announcement_date">'.$display_date.'</div>
</div>';
} else {
echo '<div class="system_announcement">
<div class="system_announcement_title">'
.$announcement->display_date.'
<a name="ann'.$announcement->id.'" href="'.$url.'?#ann'.$announcement->id.'">'.
$announcement->title.'
</a>
</div>';
}
echo '<br />';
}
echo '</div>';
}
}
/**
* @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 .= '<div class="system_announcements">';
$content .= '<h3>'.get_lang('Portal news').'</h3>';
$content .= '<table align="center">';
$content .= '<tr>';
$content .= '<td>';
$content .= self::display_arrow($user_id);
$content .= '</td>';
$content .= '</tr>';
$content .= '</table>';
$content .= '<table align="center" border="0" width="900px">';
while ($announcement = Database::fetch_object($announcements)) {
$display_date = api_convert_and_format_date($announcement->display_date, DATE_FORMAT_LONG);
$content .= '<tr><td>';
$content .= '<a name="'.$announcement->id.'"></a>
<div class="system_announcement">
<h2>'.$announcement->title.'</h2>
<div class="system_announcement_date">'.$display_date.'</div>
<br />
<div class="system_announcement_content">'
.$announcement->content.'
</div>
</div><br />';
$content .= '</tr></td>';
}
$content .= '</table>';
$content .= '<table align="center">';
$content .= '<tr>';
$content .= '<td>';
$content .= self::display_arrow($user_id);
$content .= '</td>';
$content .= '</tr>';
$content .= '</table>';
$content .= '</div>';
}
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 .= '<a href="news_list.php?start='.$next.'">'.get_lang('Next').' >> </a>';
}
} else {
echo '<a href="news_list.php?start='.$prev.'"> << '.get_lang('Prev').'</a>';
if ($nb_announcement > 20) {
$content .= '<a href="news_list.php?start='.$next.'">'.get_lang('Next').' >> </a>';
}
}
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;*/
}
}

@ -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 <gugli100@gmail.com>.
*
* @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,
]
}*/
$user = $this->getUser();
$list = [];
if (null !== $user) {
$list = $sysAnnouncementRepository->getAnnouncements(
$this->getUser(),
$this->getAccessUrl(),
$this->getRequest()->getLocale()
);
}
/**
* @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,
]
);
}
$content = SystemAnnouncementManager::getAnnouncement($id, $visibility);
return $this->render(
'@ChamiloCore/News/view.html.twig',
[
'announcement' => $content,
]
);
return new JsonResponse($list);
}
}

@ -17,13 +17,22 @@ class SysAnnouncementFixtures extends Fixture
{
$url = $this->getReference(AccessUserFixtures::ACCESS_URL_REFERENCE);
$content = '<p>
<img src="/img/document/images/mr_chamilo/svg/collaborative.svg" width="320" height="340" />
</p>
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();

@ -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;
}
}

@ -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;
}
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);
}

@ -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

@ -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;

@ -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);
}
}

@ -1,8 +0,0 @@
{% extends "@ChamiloCore/Layout/layout_one_col.html.twig" %}
{% block content %}
{% autoescape false %}
{{ toolbar }}
{{ render(controller('ChamiloCoreBundle:News:news')) }}
{% endautoescape %}
{% endblock %}

@ -1,82 +0,0 @@
{% import '@ChamiloCore/Macros/box.html.twig' as macro %}
{% autoescape false %}
{% set content %}
{% if is_granted('ROLE_ADMIN') %}
<div class="announcement-edit d-block text-right">
<a href="{{ url('index') }}main/admin/system_announcements.php" class="btn btn-primary btn-sm" >
<i class="fas fa-pencil-alt"></i> {{ "Edit this section"|trans }}
</a>
</div>
{% endif %}
{% if announcements %}
<div id="carousel-announcement" class="carousel slide" data-ride="carousel">
<ol class="carousel-indicators">
{% for announcement in announcements %}
<li data-target="#carousel-announcement"
data-slide-to="{{ loop.index0 }}" {% if loop.index0 == 0 %} class="active" {% endif %}></li>
{% endfor %}
</ol>
<div class="carousel-inner">
{% for announcement in announcements %}
<div class="carousel-item {% if loop.index0 == 0 %} active {% endif %}">
<div class="row">
<div class="col-12 col-md-6">
<div class="announcement-text">
<div class="d-md-block">
<h5>{{ announcement.title }}</h5>
{% if announcement.readMore %}
<div class="block-text">
{{ announcement.content }}
<a href="{{ _p.web }}news_list.php?id={{ announcement.id }}">{{ "More" | trans }}</a>
</div>
{% else %}
{{ announcement.content }}
{% endif %}
</div>
</div>
</div>
<div class="col-12 col-md-6">
<div class="announcement-image">
<img src="{{ announcement.picture }}" class="d-block" alt="...">
<div class="dotted-bg-block lines">
<div></div>
</div>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
<a class="carousel-control-prev" href="#carousel-announcement" role="button" data-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="carousel-control-next" href="#carousel-announcement" role="button" data-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
{% else %}
<div class="row">
<div class="col-md-6">
<div class="block-platform d-none d-block">
<h1>{{ "Accelerate your future. Learn where you want and when you want"|trans }}</h1>
<h5>{{ "Develop your skills with Chamilo 2.0"|trans }}</h5>
</div>
</div>
<div class="col-md-6">
<img class="d-block w-100" data-src="slide" alt="" src="{{ asset('img/intro_chamilo.svg') }}"
data-holder-rendered="true">
</div>
</div>
{% endif %}
{% endset %}
{{ content }}
{% endautoescape %}

@ -1,24 +0,0 @@
{% extends "@ChamiloCore/Layout/layout_one_col.html.twig" %}
{% block content %}
{% autoescape false %}
<div class="page-header">
<h4>{{ "SystemAnnouncements" | trans }}</h4>
</div>
{% if not announcement is empty %}
<article id="announcement-{{ announcement.id }}}">
<div class="page-header">
<h3>{{ announcement.title }}</h3>
{{ announcement.content }}
</div>
</article>
{% else %}
<div class="alert alert-danger" role="alert">
{{ "NoResults" | trans }}
</div>
{% endif %}
{% endautoescape %}
{% endblock %}

@ -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;

@ -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
*/

Loading…
Cancel
Save