Merge pull request #5259 from christianbeeznest/fixes-updates2

Internal: Improve forum UI and fix bugs
pull/5260/head
christianbeeznest 2 years ago committed by GitHub
commit 57213dc65f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 47
      assets/css/app.scss
  2. 39
      assets/css/scss/_exercise.scss
  3. 201
      assets/css/scss/_forums.scss
  4. 47
      public/main/forum/forumfunction.inc.php
  5. 11
      public/main/forum/index.php
  6. 2
      public/main/forum/viewthread.php
  7. 13
      public/main/template/default/forum/list.html.twig
  8. 5
      public/main/template/default/forum/posts.html.twig
  9. 3
      src/CoreBundle/EventListener/CourseListener.php
  10. 2
      src/CoreBundle/EventListener/ExceptionListener.php

@ -141,6 +141,45 @@
} }
} }
// Card
.card {
border: 1px solid #ddd;
border-radius: 4px;
box-shadow: 0 2px 5px rgba(0,0,0,0.15);
background-color: #fff;
margin-bottom: 20px;
}
.card .flex {
display: flex;
justify-content: space-between;
align-items: center;
}
.card .flex .relative {
position: relative;
font-size: 16px;
font-weight: bold;
}
.card .flex a {
margin-left: 10px;
font-size: 18px;
color: #333;
}
.card .sectioncomment {
padding: 15px;
background-color: #f7f7f7;
}
.card span {
float: right;
margin-right: 15px;
font-size: 14px;
color: #666;
}
// Alerts // Alerts
.alert { .alert {
@ -337,14 +376,6 @@
text-decoration: underline; text-decoration: underline;
} }
.category-forum .custom-panel-group {
width: 100%;
}
.category-forum .forum_display {
padding: 20px 0px;
}
#date_fields label, #date_fields label,
.p-float-label .datepicker-label { .p-float-label .datepicker-label {
top: 0px; top: 0px;

@ -322,45 +322,6 @@
} }
} }
.card {
border: 1px solid #ddd;
border-radius: 4px;
box-shadow: 0 2px 5px rgba(0,0,0,0.15);
background-color: #fff;
margin-bottom: 20px;
}
.card .flex {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 15px;
}
.card .flex .relative {
position: relative;
font-size: 16px;
font-weight: bold;
}
.card .flex a {
margin-left: 10px;
font-size: 22px;
color: #333;
}
.card .sectioncomment {
padding: 15px;
background-color: #f7f7f7;
}
.card span {
float: right;
margin-right: 15px;
font-size: 14px;
color: #666;
}
.question_menu { .question_menu {
@apply p-4 flex flex-row gap-1; @apply p-4 flex flex-row gap-1;
} }

@ -76,3 +76,204 @@
.ch-tool-icon-disabled { .ch-tool-icon-disabled {
@apply text-gray-50; @apply text-gray-50;
} }
.category-forum {
.custom-panel-group {
border: none;
margin: 0;
width: 100%;
}
.custom-panel {
box-shadow: 0 2px 5px rgba(0,0,0,0.2);
margin-bottom: 10px;
border-radius: 4px;
overflow: hidden;
}
.custom-panel-heading {
padding: 10px 15px;
background-color: #f8f8f8;
border-bottom: 1px solid #ddd;
cursor: pointer;
display: flex;
align-items: center;
}
.custom-panel-heading .open {
flex-shrink: 0;
}
.custom-panel-heading h4 {
margin: 0;
padding: 0;
font-size: 18px;
color: #333;
flex-grow: 1;
text-align: left;
}
.custom-panel-title {
margin-left: 10px;
}
.pull-right a {
margin-left: 10px;
}
.custom-panel-body {
padding: 15px;
background-color: #fff;
}
}
.forum_display {
display: flex;
width: 100%;
margin-bottom: 15px;
border: 1px solid #ddd;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
.forum-row {
width: 100%;
padding: 5px;
}
.card-forum {
display: flex;
flex-direction: row;
width: 100%;
padding: 10px;
align-items: flex-start;
background-color: #fff;
}
.number-post {
text-align: center;
flex: 0 0 25%;
padding: 30px;
border-right: 1px solid #ddd;
background-color: #f5f5f5;
display: flex;
flex-direction: column;
align-items: center;
margin-right: 20px;
}
.number-post i {
font-size: 48px;
color: #3276b1;
}
.number-post p {
font-size: 14px;
margin-top: 8px;
}
.content-forum {
display: flex;
flex-direction: column;
flex-grow: 1;
padding-left: 15px;
}
.title-forum {
font-size: 18px;
margin: 0;
}
.description-forum {
font-size: 14px;
color: #666;
margin-top: 4px;
}
.actions-forum {
margin-left: auto;
display: flex;
align-items: center;
justify-content: flex-end;
}
.actions-forum i {
font-size: 22px;
margin-left: 10px;
cursor: pointer;
}
@media (max-width: 768px) {
flex-direction: column;
.number-post {
border-right: none;
border-bottom: 1px solid #ddd;
order: -1;
width: 100%;
padding: 15px;
}
.content-forum {
padding: 15px;
}
.actions-forum {
justify-content: center;
margin-top: 10px;
}
}
}
.forum-post {
.post-col1 {
display: flex;
flex-direction: column;
align-items: center;
padding: 10px;
width: 15% !important;
}
.q-avatar {
border-radius: 50%;
overflow: hidden;
width: 80px;
height: 80px;
}
.q-avatar img {
width: 100%;
height: auto;
}
.post-date {
margin-top: 10px;
font-size: 0.8rem;
color: #666;
}
.flex-row {
display: flex;
margin-top: 10px;
}
.boot-tooltip {
position: relative;
}
.boot-tooltip::before {
content: attr(title);
position: absolute;
bottom: 100%;
left: 50%;
transform: translateX(-50%);
background: black;
color: white;
padding: 5px;
border-radius: 4px;
font-size: 0.7rem;
display: none;
}
.boot-tooltip:hover::before {
display: block;
}
}

@ -1164,14 +1164,9 @@ function getForum(
} }
/** /**
* Retrieve all the threads of a given forum. * Retrieves all the threads for a given forum or counts them.
*
* @param int|null $courseId Optional If is null then it is considered the current course
* @param int|null $sessionId Optional. If is null then it is considered the current session
*
* @return CForumThread[]
*/ */
function get_threads(int $forumId, int $courseId = null, int $sessionId = null): Array function get_threads(int $forumId, int $courseId = null, int $sessionId = null, bool $count = false): array|int
{ {
$repo = Container::getForumThreadRepository(); $repo = Container::getForumThreadRepository();
$courseId = empty($courseId) ? api_get_course_int_id() : $courseId; $courseId = empty($courseId) ? api_get_course_int_id() : $courseId;
@ -1181,8 +1176,13 @@ function get_threads(int $forumId, int $courseId = null, int $sessionId = null):
$qb = $repo->getResourcesByCourse($course, $session); $qb = $repo->getResourcesByCourse($course, $session);
$qb->andWhere('resource.forum = :forum')->setParameter('forum', $forumId); $qb->andWhere('resource.forum = :forum')->setParameter('forum', $forumId);
if ($count) {
$qb->select('COUNT(resource.iid)');
return (int) $qb->getQuery()->getSingleScalarResult();
} else {
return $qb->getQuery()->getResult(); return $qb->getQuery()->getResult();
} }
}
/** /**
* Get a thread by Id and course id. * Get a thread by Id and course id.
@ -1985,8 +1985,8 @@ function show_add_post_form(CForum $forum, CForumThread $thread, CForumPost $pos
'add_attachment', 'add_attachment',
get_lang('Add attachment'), get_lang('Add attachment'),
'paperclip', 'paperclip',
'default', 'plain',
'default', 'plain',
null, null,
['id' => 'reply-add-attachment'] ['id' => 'reply-add-attachment']
); );
@ -3286,7 +3286,6 @@ function handle_mail_cue($content, $id)
$sql = "SELECT users.firstname, users.lastname, users.id as user_id, users.email $sql = "SELECT users.firstname, users.lastname, users.id as user_id, users.email
FROM $table_mailcue mailcue, $table_posts posts, $table_users users FROM $table_mailcue mailcue, $table_posts posts, $table_users users
WHERE WHERE
posts.c_id = $course_id AND
mailcue.c_id = $course_id AND mailcue.c_id = $course_id AND
posts.thread_id = $thread_id AND posts.thread_id = $thread_id AND
posts.post_notification = '1' AND posts.post_notification = '1' AND
@ -3326,14 +3325,14 @@ function handle_mail_cue($content, $id)
Database::query($sql); Database::query($sql);
} elseif ('forum' === $content) { } elseif ('forum' === $content) {
$sql = "SELECT iid FROM $table_threads $sql = "SELECT iid FROM $table_threads
WHERE c_id = $course_id AND forum_id = $id"; WHERE forum_id = $id";
$result = Database::query($sql); $result = Database::query($sql);
while ($row = Database::fetch_array($result)) { while ($row = Database::fetch_array($result)) {
handle_mail_cue('thread', $row['iid']); handle_mail_cue('thread', $row['iid']);
} }
} elseif ('forum_category' === $content) { } elseif ('forum_category' === $content) {
$sql = "SELECT iid FROM $table_forums $sql = "SELECT iid FROM $table_forums
WHERE c_id = $course_id AND forum_category = $id"; WHERE forum_category = $id";
$result = Database::query($sql); $result = Database::query($sql);
while ($row = Database::fetch_array($result)) { while ($row = Database::fetch_array($result)) {
handle_mail_cue('forum', $row['iid']); handle_mail_cue('forum', $row['iid']);
@ -3550,22 +3549,22 @@ function store_move_post($values)
// Moving the post to the newly created thread. // Moving the post to the newly created thread.
$sql = "UPDATE $table_posts SET thread_id='".$new_thread_id."', post_parent_id = NULL $sql = "UPDATE $table_posts SET thread_id='".$new_thread_id."', post_parent_id = NULL
WHERE c_id = $course_id AND iid ='".(int) ($values['post_id'])."'"; WHERE iid ='".(int) ($values['post_id'])."'";
Database::query($sql); Database::query($sql);
// Resetting the parent_id of the thread to 0 for all those who had this moved post as parent. // Resetting the parent_id of the thread to 0 for all those who had this moved post as parent.
$sql = "UPDATE $table_posts SET post_parent_id = NULL $sql = "UPDATE $table_posts SET post_parent_id = NULL
WHERE c_id = $course_id AND post_parent_id='".(int) ($values['post_id'])."'"; WHERE post_parent_id='".(int) ($values['post_id'])."'";
Database::query($sql); Database::query($sql);
// Updating updating the number of threads in the forum. // Updating updating the number of threads in the forum.
$sql = "UPDATE $table_forums SET forum_threads=forum_threads+1 $sql = "UPDATE $table_forums SET forum_threads=forum_threads+1
WHERE c_id = $course_id AND iid ='".$forumId."'"; WHERE iid ='".$forumId."'";
Database::query($sql); Database::query($sql);
// Resetting the last post of the old thread and decreasing the number of replies and the thread. // Resetting the last post of the old thread and decreasing the number of replies and the thread.
$sql = "SELECT * FROM $table_posts $sql = "SELECT * FROM $table_posts
WHERE c_id = $course_id AND thread_id='".$threadId."' WHERE thread_id='".$threadId."'
ORDER BY iid DESC"; ORDER BY iid DESC";
$result = Database::query($sql); $result = Database::query($sql);
$row = Database::fetch_array($result); $row = Database::fetch_array($result);
@ -3573,19 +3572,18 @@ function store_move_post($values)
thread_last_post='".$row['iid']."', thread_last_post='".$row['iid']."',
thread_replies=thread_replies-1 thread_replies=thread_replies-1
WHERE WHERE
c_id = $course_id AND
iid ='".$threadId."'"; iid ='".$threadId."'";
Database::query($sql); Database::query($sql);
} else { } else {
// Moving to the chosen thread. // Moving to the chosen thread.
$sql = 'SELECT thread_id FROM '.$table_posts." $sql = 'SELECT thread_id FROM '.$table_posts."
WHERE c_id = $course_id AND iid = '".$values['post_id']."' "; WHERE iid = '".$values['post_id']."' ";
$result = Database::query($sql); $result = Database::query($sql);
$row = Database::fetch_array($result); $row = Database::fetch_array($result);
$original_thread_id = $row['thread_id']; $original_thread_id = $row['thread_id'];
$sql = 'SELECT thread_last_post FROM '.$table_threads." $sql = 'SELECT thread_last_post FROM '.$table_threads."
WHERE c_id = $course_id AND iid = '".$original_thread_id."' "; WHERE iid = '".$original_thread_id."' ";
$result = Database::query($sql); $result = Database::query($sql);
$row = Database::fetch_array($result); $row = Database::fetch_array($result);
@ -3595,7 +3593,6 @@ function store_move_post($values)
if ($thread_is_last_post == $values['post_id']) { if ($thread_is_last_post == $values['post_id']) {
$sql = 'SELECT iid as post_id FROM '.$table_posts." $sql = 'SELECT iid as post_id FROM '.$table_posts."
WHERE WHERE
c_id = $course_id AND
thread_id = '".$original_thread_id."' AND thread_id = '".$original_thread_id."' AND
iid <> '".$values['post_id']."' iid <> '".$values['post_id']."'
ORDER BY post_date DESC LIMIT 1"; ORDER BY post_date DESC LIMIT 1";
@ -3606,26 +3603,26 @@ function store_move_post($values)
$sql = 'UPDATE '.$table_threads." $sql = 'UPDATE '.$table_threads."
SET thread_last_post = '".$thread_new_last_post."' SET thread_last_post = '".$thread_new_last_post."'
WHERE c_id = $course_id AND iid = '".$original_thread_id."' "; WHERE iid = '".$original_thread_id."' ";
Database::query($sql); Database::query($sql);
} }
$sql = "UPDATE $table_threads SET thread_replies=thread_replies-1 $sql = "UPDATE $table_threads SET thread_replies=thread_replies-1
WHERE c_id = $course_id AND iid ='".$original_thread_id."'"; WHERE iid ='".$original_thread_id."'";
Database::query($sql); Database::query($sql);
// moving to the chosen thread // moving to the chosen thread
$sql = "UPDATE $table_posts SET thread_id='".(int) ($_POST['thread'])."', post_parent_id = NULL $sql = "UPDATE $table_posts SET thread_id='".(int) ($_POST['thread'])."', post_parent_id = NULL
WHERE c_id = $course_id AND iid ='".(int) ($values['post_id'])."'"; WHERE iid ='".(int) ($values['post_id'])."'";
Database::query($sql); Database::query($sql);
// resetting the parent_id of the thread to 0 for all those who had this moved post as parent // resetting the parent_id of the thread to 0 for all those who had this moved post as parent
$sql = "UPDATE $table_posts SET post_parent_id = NULL $sql = "UPDATE $table_posts SET post_parent_id = NULL
WHERE c_id = $course_id AND post_parent_id='".(int) ($values['post_id'])."'"; WHERE post_parent_id='".(int) ($values['post_id'])."'";
Database::query($sql); Database::query($sql);
$sql = "UPDATE $table_threads SET thread_replies=thread_replies+1 $sql = "UPDATE $table_threads SET thread_replies=thread_replies+1
WHERE c_id = $course_id AND iid ='".(int) ($_POST['thread'])."'"; WHERE iid ='".(int) ($_POST['thread'])."'";
Database::query($sql); Database::query($sql);
} }

@ -262,6 +262,13 @@ if ($translate) {
placeholder: "'.get_lang('Select a language').'", placeholder: "'.get_lang('Select a language').'",
allowClear: true allowClear: true
}); });
$("#extra_language").on("change", function() {
var selectedLanguages = $(this).val();
if (selectedLanguages.length === 0) {
window.location.reload();
}
});
}); });
</script>'; </script>';
$form = new FormValidator('search_simple', 'get', api_get_self().'?'.api_get_cidreq(), null, null); $form = new FormValidator('search_simple', 'get', api_get_self().'?'.api_get_cidreq(), null, null);
@ -447,9 +454,7 @@ if (is_array($forumCategories)) {
$groupId = $forum->getForumOfGroup(); $groupId = $forum->getForumOfGroup();
$forumInfo['visibility'] = $forumVisibility = $forum->isVisible($courseEntity); $forumInfo['visibility'] = $forumVisibility = $forum->isVisible($courseEntity);
/*$forumInfo['number_threads'] = isset($forum['number_of_threads']) $forumInfo['number_threads'] = (int) get_threads($forumId, api_get_course_int_id(), api_get_session_id(), true);
? (int) $forum['number_of_threads']
: 0;*/
$linkForum = api_get_path(WEB_CODE_PATH).'forum/viewforum.php?'.api_get_cidreq() $linkForum = api_get_path(WEB_CODE_PATH).'forum/viewforum.php?'.api_get_cidreq()
.'&gid='.$groupId.'&forum='.$forumId; .'&gid='.$groupId.'&forum='.$forumId;

@ -446,7 +446,7 @@ foreach ($posts as $post) {
get_lang('Edit'), get_lang('Edit'),
$editUrl, $editUrl,
'pencil', 'pencil',
'default' 'plain'
); );
} }
} }

@ -7,7 +7,7 @@
<script> <script>
$(function () { $(function () {
// default // default
$('.category-forum ').hide(); //$('.category-forum ').hide();
{% if default_user_language %} {% if default_user_language %}
$('.{{ default_user_language }}').show(); $('.{{ default_user_language }}').show();
@ -97,9 +97,9 @@
</div> </div>
{% for subitem in item.forums %} {% for subitem in item.forums %}
<div class="forum_display w-full"> <div class="forum_display w-full">
<div class="card"> <div class="card-forum">
<div class="flex flex-row"> <div class="flex flex-row forum-row">
<div class="w-1/5"> <div class="w-1/5 float-left">
<div class="number-post"> <div class="number-post">
<a href="{{ subitem.url }}" title="{{subitem.title}}"> <a href="{{ subitem.url }}" title="{{subitem.title}}">
{% if subitem.forum_image is not empty %} {% if subitem.forum_image is not empty %}
@ -112,12 +112,11 @@
{% endif %} {% endif %}
{% endif %} {% endif %}
</a> </a>
{# <p>{{ 'Forum threads'| trans }}: {{ subitem.number_threads }} </p>#} <p>{{ 'Forum threads'| trans }}: {{ subitem.number_threads }} </p>
</div> </div>
</div> </div>
<div class="w-4/5 flex flex-row justify-between"> <div class="w-4/5 justify-between float-right">
<h3 class="text-lg flex flex-row"> <h3 class="text-lg flex flex-row">
{{ 'ObjectIcon::FORUM'|mdi_icon(32) }}
<a href="{{ subitem.url }}" title="{{ subitem.title }}" class="{{ subitem.visibility != '1' ? 'text-muted': '' }}">{{ subitem.title }}</a> <a href="{{ subitem.url }}" title="{{ subitem.title }}" class="{{ subitem.visibility != '1' ? 'text-muted': '' }}">{{ subitem.title }}</a>
{# {% if subitem.forum_of_group != 0 %}#} {# {% if subitem.forum_of_group != 0 %}#}
{# <a class="forum-goto" href="../group/group_space.php?cid={{ course.id }}&sid={{ session.id }}&gid={{ subitem.forum_of_group }}">#} {# <a class="forum-goto" href="../group/group_space.php?cid={{ course.id }}&sid={{ session.id }}&gid={{ subitem.forum_of_group }}">#}

@ -16,15 +16,16 @@
{% for post in posts %} {% for post in posts %}
{% set post_data %} {% set post_data %}
<div class="flex flex-row"> <div class="flex flex-row">
<div class="w-1/5"> <div class="w-1/5 post-col1">
{% set image %} {% set image %}
<img src="{{ post.author | illustration }}?w=80&h=80&fit=crop" /> <img src="{{ post.author | illustration }}?w=80&h=80&fit=crop" />
{% endset %} {% endset %}
{{ display.avatar(image, 80) }} {{ display.avatar(image, 80) }}
{{ post.author }}
{{ post.post_date_to_display }} {{ post.post_date_to_display }}
<div class='flex flex-row'> <div class='flex flex-row border border-gray-25'>
{{ post.tool_icons }} {{ post.tool_icons }}
</div> </div>

@ -10,6 +10,7 @@ use Chamilo\CoreBundle\Controller\EditorController;
use Chamilo\CoreBundle\Entity\Course; use Chamilo\CoreBundle\Entity\Course;
use Chamilo\CoreBundle\Entity\Session; use Chamilo\CoreBundle\Entity\Session;
use Chamilo\CoreBundle\Entity\User; use Chamilo\CoreBundle\Entity\User;
use Chamilo\CoreBundle\Exception\NotAllowedException;
use Chamilo\CoreBundle\Security\Authorization\Voter\CourseVoter; use Chamilo\CoreBundle\Security\Authorization\Voter\CourseVoter;
use Chamilo\CoreBundle\Security\Authorization\Voter\GroupVoter; use Chamilo\CoreBundle\Security\Authorization\Voter\GroupVoter;
use Chamilo\CoreBundle\Security\Authorization\Voter\SessionVoter; use Chamilo\CoreBundle\Security\Authorization\Voter\SessionVoter;
@ -117,7 +118,7 @@ class CourseListener
$twig->addGlobal('course', $course); $twig->addGlobal('course', $course);
if (false === $checker->isGranted(CourseVoter::VIEW, $course)) { if (false === $checker->isGranted(CourseVoter::VIEW, $course)) {
throw new AccessDeniedException($this->translator->trans('You\'re not allowed in this course')); throw new NotAllowedException($this->translator->trans('You\'re not allowed in this course'));
} }
// Checking if sid is used. // Checking if sid is used.

@ -35,7 +35,7 @@ class ExceptionListener
$exception = $event->getThrowable(); $exception = $event->getThrowable();
$request = $event->getRequest(); $request = $event->getRequest();
if ($exception instanceof AccessDeniedException || $exception instanceof NotAllowedException) { if ($exception instanceof NotAllowedException) {
if (null === $this->tokenStorage->getToken()) { if (null === $this->tokenStorage->getToken()) {
$currentUrl = $request->getUri(); $currentUrl = $request->getUri();
$parsedUrl = parse_url($currentUrl); $parsedUrl = parse_url($currentUrl);

Loading…
Cancel
Save