Update moderated posts with a button using ajax.

Show pending moderation post label. see BT#10894
pull/2487/head
jmontoyaa 9 years ago
parent 46ed165fd6
commit af34a182b3
  1. 7
      main/forum/editpost.php
  2. 111
      main/forum/forumfunction.inc.php
  3. 15
      main/forum/index.php
  4. 22
      main/forum/viewforum.php
  5. 18
      main/forum/viewforumcategory.php
  6. 19
      main/forum/viewthread.php
  7. 69
      main/forum/viewthread_nested.inc.php
  8. 79
      main/inc/ajax/forum.ajax.php
  9. 27
      main/inc/lib/display.lib.php
  10. 6
      main/lang/english/trad4all.inc.php
  11. 2
      main/lp/learnpath.class.php

@ -134,10 +134,11 @@ JS;
// 4. if editing of replies is not allowed
// The only exception is the course manager
// I have split this is several pieces for clarity.
//if (!api_is_allowed_to_edit() AND (($current_forum_category['visibility'] == 0 OR $current_forum['visibility'] == 0) OR ($current_forum_category['locked'] <> 0 OR $current_forum['locked'] <> 0 OR $current_thread['locked'] <> 0))) {
if (!api_is_allowed_to_edit(null, true) &&
(($current_forum_category && $current_forum_category['visibility'] == 0) ||
$current_forum['visibility'] == 0)
(
($current_forum_category && $current_forum_category['visibility'] == 0) ||
$current_forum['visibility'] == 0
)
) {
api_not_allowed(true);
}

@ -25,6 +25,7 @@ use Chamilo\CourseBundle\Entity\CForumThread;
* @todo several functions have to be moved to the itemmanager library
* @todo displaying icons => display library
* @todo complete the missing phpdoc the correct order should be
* @todo convert into a class
*/
define('FORUM_NEW_POST', 0);
@ -1931,8 +1932,14 @@ function getThreadInfo($threadId, $cId)
*
* @return array containing all the information about the posts of a given thread
*/
function getPosts($forumInfo, $threadId, $orderDirection = 'ASC', $recursive = false, $postId = null, $depth = -1)
{
function getPosts(
$forumInfo,
$threadId,
$orderDirection = 'ASC',
$recursive = false,
$postId = null,
$depth = -1
) {
$em = Database::getManager();
if (api_is_allowed_to_edit(false, true)) {
@ -1957,15 +1964,11 @@ function getPosts($forumInfo, $threadId, $orderDirection = 'ASC', $recursive = f
$filterModerated = false;
}
} else {
if (GroupManager::is_tutor_of_group(api_get_user_id(), $groupInfo['iid']) || api_is_allowed_to_edit()) {
if (GroupManager::is_tutor_of_group(api_get_user_id(), $groupInfo['iid']) || api_is_allowed_to_edit(false, true)) {
$filterModerated = false;
}
}
if ($filterModerated && $forumInfo['moderated'] == 1) {
$criteria->andWhere(Criteria::expr()->eq('status', 1));
}
if ($recursive) {
$criteria->andWhere(Criteria::expr()->eq('postParentId', $postId));
}
@ -1975,8 +1978,20 @@ function getPosts($forumInfo, $threadId, $orderDirection = 'ASC', $recursive = f
->addCriteria($criteria)
->addOrderBy('p.postId', $orderDirection);
$posts = $qb->getQuery()->getResult();
if ($filterModerated && $forumInfo['moderated'] == 1) {
if (!api_is_allowed_to_edit(false, true)) {
$userId = api_get_user_id();
$qb->andWhere(
"p.status = 1 OR
(p.status = ".CForumPost::STATUS_WAITING_MODERATION." AND p.posterId = $userId) OR
(p.status IS NULL AND p.posterId = $userId)
"
);
}
}
$posts = $qb->getQuery()->getResult();
$depth++;
$list = [];
@ -2018,7 +2033,6 @@ function getPosts($forumInfo, $threadId, $orderDirection = 'ASC', $recursive = f
if (!$recursive) {
continue;
}
$list = array_merge(
$list,
getPosts(
@ -6057,24 +6071,93 @@ function getForumCategoryByTitle($title, $courseId, $sessionId = 0)
return $resultData;
}
function getPostStatus($current_forum, $row)
/**
* @param array $current_forum
* @param array $row
*
* @return string
*/
function getPostStatus($current_forum, $row, $addWrapper = true)
{
$statusIcon = '';
if ($current_forum['moderated']) {
$statusIcon = '<br /><br />';
if ($addWrapper) {
$statusIcon = '<br /><br /><span id="status_post_'.$row['iid'].'">';
}
$row['status'] = empty($row['status']) ? 2 : $row['status'];
$addUrl = false;
if (api_is_allowed_to_edit(false, true)) {
$addUrl = true;
}
$label = '';
$icon = '';
$buttonType = '';
switch ($row['status']) {
case CForumPost::STATUS_VALIDATED:
$statusIcon .= Display::label(get_lang('Validated'), 'success');
$label = get_lang('Validated');
$icon = 'check-circle';
$buttonType = 'success';
break;
case CForumPost::STATUS_WAITING_MODERATION:
$statusIcon .= Display::label(get_lang('WaitingModeration'), 'warning');
$label = get_lang('WaitingModeration');
$icon = 'warning';
$buttonType = 'warning';
break;
case CForumPost::STATUS_REJECTED:
$statusIcon .= Display::label(get_lang('Rejected'), 'danger');
$label = get_lang('Rejected');
$icon = 'minus-circle';
$buttonType = 'danger';
break;
}
if ($addUrl) {
$statusIcon .= Display::toolbarButton(
$label.'&nbsp;',
'javascript:void(0)',
$icon,
$buttonType,
['class' => 'change_post_status']
);
} else {
$statusIcon .= Display::label(
Display::returnFontAwesomeIcon($icon).$label,
$buttonType
);
}
if ($addWrapper) {
$statusIcon .= '</span>';
}
}
return $statusIcon;
}
/**
* @param array $forumInfo
* @param int $threadId
* @param int $status
* @return mixed
*/
function getCountPostsWithStatus($status, $forumInfo, $threadId = null)
{
$em = Database::getManager();
$criteria = Criteria::create();
$criteria
->where(Criteria::expr()->eq('status', $status))
->andWhere(Criteria::expr()->eq('cId', $forumInfo['c_id']))
->andWhere(Criteria::expr()->eq('visible', 1))
;
if (!empty($threadId)) {
$criteria->andWhere(Criteria::expr()->eq('threadId', $threadId));
}
$qb = $em->getRepository('ChamiloCourseBundle:CForumPost')->createQueryBuilder('p');
$qb->select('count(p.iid)')
->addCriteria($criteria);
return $qb->getQuery()->getSingleScalarResult();
}

@ -2,6 +2,7 @@
/* For licensing terms, see /license.txt */
use ChamiloSession as Session;
use Chamilo\CourseBundle\Entity\CForumPost;
/**
* These files are a complete rework of the forum. The database structure is
@ -509,6 +510,20 @@ if (is_array($forumCategories)) {
'class'=>'description'
]
);
if ($forum['moderated'] == 1 && api_is_allowed_to_edit(false, true)) {
$waitingCount = getCountPostsWithStatus(
CForumPost::STATUS_WAITING_MODERATION,
$forum
);
if (!empty($waitingCount)) {
$html .= Display::label(
get_lang('PostsPendingModeration'). ': '.$waitingCount,
'warning'
);
}
}
$html .= '</div>';
$html .= '</div>';

@ -1,6 +1,8 @@
<?php
/* For licensing terms, see /license.txt */
use Chamilo\CourseBundle\Entity\CForumPost;
/**
* These files are a complete rework of the forum. The database structure is
* based on phpBB but all the code is rewritten. A lot of new functionalities
@ -460,11 +462,8 @@ if (is_array($threads)) {
$newPost = '';
}
if ($row['thread_sticky'] == 1) {
//$sticky = Display::return_icon('exclamation.gif');
}
$name = api_get_person_name($row['firstname'], $row['lastname']);
$linkPostForum = '<a href="viewthread.php?' . api_get_cidreq() . '&forum=' . Security::remove_XSS($my_forum)
. "&origin=$origin&thread={$row['thread_id']}&search="
. Security::remove_XSS(urlencode($my_search)) . '">'
@ -514,6 +513,21 @@ if (is_array($threads)) {
);
$html .= '<p>'. get_lang('By') .' ' .$authorName.'</p>';
$html .= '<p>' . api_convert_and_format_date($row['insert_date']) . '</p>';
if ($current_forum['moderated'] == 1 && api_is_allowed_to_edit(false, true)) {
$waitingCount = getCountPostsWithStatus(
CForumPost::STATUS_WAITING_MODERATION,
$current_forum,
$row['thread_id']
);
if (!empty($waitingCount)) {
$html .= Display::label(
get_lang('PostsPendingModeration'). ': '.$waitingCount,
'warning'
);
}
}
$html .= '</div>';
$html .= '</div>';

@ -1,6 +1,8 @@
<?php
/* For licensing terms, see /license.txt */
use Chamilo\CourseBundle\Entity\CForumPost;
/**
* These files are a complete rework of the forum. The database structure is
* based on phpBB but all the code is rewritten. A lot of new functionalities
@ -268,7 +270,7 @@ if ($action_forums != 'add') {
// SHOULD WE SHOW THIS PARTICULAR FORUM
// you are teacher => show forum
if (api_is_allowed_to_edit(false,true)) {
if (api_is_allowed_to_edit(false, true)) {
//echo 'teacher';
$show_forum = true;
} else {
@ -390,6 +392,20 @@ if ($action_forums != 'add') {
'class' => 'description'
)
);
if ($forum['moderated'] == 1 && api_is_allowed_to_edit(false, true)) {
$waitingCount = getCountPostsWithStatus(
CForumPost::STATUS_WAITING_MODERATION,
$forum
);
if (!empty($waitingCount)) {
$html .= Display::label(
get_lang('PostsPendingModeration'). ': '.$waitingCount,
'warning'
);
}
}
$html .= '</div>';
$html .= '</div>';
$html .= '<div class="col-md-6">';

@ -59,6 +59,25 @@ $groupId = api_get_group_id();
$group_properties = GroupManager::get_group_properties($groupId);
$sessionId = api_get_session_id();
$ajaxURL = api_get_path(WEB_AJAX_PATH).'forum.ajax.php?'.api_get_cidreq().'&a=change_post_status';
$htmlHeadXtra[] = '<script>
$(function() {
$("span").on("click", ".change_post_status", function() {
var updateDiv = $(this).parent();
var postId = updateDiv.attr("id");
$.ajax({
url: "'.$ajaxURL.'&post_id="+postId,
type: "GET",
success: function(data) {
updateDiv.html(data);
}
});
});
});
</script>';
if ($origin == 'group') {
$interbreadcrumb[] = array(
'url' => api_get_path(WEB_CODE_PATH).'group/group.php?'.api_get_cidreq(),

@ -1,6 +1,8 @@
<?php
/* For licensing terms, see /license.txt */
use Chamilo\CourseBundle\Entity\CForumPost;
/**
* @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
* @author Julio Montoya <gugli100@gmail.com> UI Improvements + lots of bugfixes
@ -37,6 +39,8 @@ $userId = api_get_user_id();
$groupInfo = GroupManager::get_group_properties($group_id);
$postCount = 1;
$allowUserImageForum = api_get_course_setting('allow_user_image_forum');
foreach ($rows as $post) {
// The style depends on the status of the message: approved or not.
if ($post['visible'] == '0') {
@ -55,11 +59,9 @@ foreach ($rows as $post) {
$html .= '<div class="col-md-offset-' . $indent . '" >';
$html .= '<div class="panel panel-default forum-post">';
$html .= '<div class="panel-body">';
$html .= '<div class="row">';
$html .= '<div class="col-md-2">';
$username = sprintf(get_lang('LoginX'), $post['username']);
if ($post['user_id'] == '0') {
$name = $post['poster_name'];
@ -68,7 +70,7 @@ foreach ($rows as $post) {
}
if ($origin != 'learnpath') {
if (api_get_course_setting('allow_user_image_forum')) {
if ($allowUserImageForum) {
$html .= '<div class="thumbnail">' . display_user_image($post['user_id'], $name, $origin) . '</div>';
}
@ -78,7 +80,7 @@ foreach ($rows as $post) {
array('class' => 'title-username')
);
} else {
if (api_get_course_setting('allow_user_image_forum')) {
if ($allowUserImageForum) {
$html .= '<div class="thumbnail">' . display_user_image($post['user_id'], $name, $origin) . '</div>';
}
@ -95,13 +97,13 @@ foreach ($rows as $post) {
if ($origin != 'learnpath') {
$html .= Display::tag(
'p',
api_convert_and_format_date($post['post_date']),
Display::dateToStringAgoAndLongDate($post['post_date']),
array('class' => 'post-date')
);
} else {
$html .= Display::tag(
'p',
api_convert_and_format_date($post['post_date'], DATE_TIME_FORMAT_SHORT),
Display::dateToStringAgoAndLongDate($post['post_date']),
array('class' => 'text-muted')
);
}
@ -111,25 +113,34 @@ foreach ($rows as $post) {
$id_attach = !empty($attachment_list) ? $attachment_list['iid'] : '';
$iconEdit = '';
$editButton = '';
// The user who posted it can edit his thread only if the course admin allowed this in the properties of the forum
// The course admin him/herself can do this off course always
if (
(isset($groupInfo['iid']) &&GroupManager::is_tutor_of_group(api_get_user_id(), $groupInfo['iid'])) ||
$tutorGroup = GroupManager::is_tutor_of_group(api_get_user_id(), $groupInfo['iid']);
if ((isset($groupInfo['iid']) && $tutorGroup) ||
($current_forum['allow_edit'] == 1 && $post['user_id'] == $userId) ||
(api_is_allowed_to_edit(false, true) && !(api_is_course_coach() && $current_forum['session_id'] != $sessionId))
) {
if ($locked == false) {
$iconEdit .= "<a href=\"editpost.php?" . api_get_cidreq()
. "&forum=$clean_forum_id&thread=$clean_thread_id&post={$post['post_id']}&id_attach=$id_attach"
. "\">"
$editUrl = api_get_path(WEB_CODE_PATH).'forum/editpost.php?'.api_get_cidreq();
$editUrl .= "&forum=$clean_forum_id&thread=$clean_thread_id&post={$post['post_id']}&id_attach=$id_attach";
$iconEdit .= "<a href='".$editUrl."'>"
. Display::return_icon('edit.png', get_lang('Edit'), array(), ICON_SIZE_SMALL)
. "</a>";
$editButton = Display::toolbarButton(
get_lang('Edit'),
$editUrl,
'pencil',
'default'
);
}
}
if (
(isset($groupInfo['iid']) && GroupManager::is_tutor_of_group(api_get_user_id(), $groupInfo['iid'])) ||
if ((isset($groupInfo['iid']) && $tutorGroup) ||
api_is_allowed_to_edit(false, true) &&
!(api_is_course_coach() && $current_forum['session_id'] != $sessionId)
) {
@ -190,7 +201,9 @@ foreach ($rows as $post) {
if ($userCanQualify) {
if ($count > 0) {
$current_qualify_thread = showQualify(
'1', $post['user_id'], $_GET['thread']
'1',
$post['user_id'],
$_GET['thread']
);
if ($locked == false) {
$iconEdit .= "<a href=\"forumqualify.php?" . api_get_cidreq()
@ -208,6 +221,10 @@ foreach ($rows as $post) {
$html .= '<div class="tools-icons">' . $iconEdit . ' '.$statusIcon.'</div>';
}
$buttonReply = '';
$buttonQuote = '';
$waitingValidation = '';
if (($current_forum_category && $current_forum_category['locked'] == 0) &&
$current_forum['locked'] == 0 && $current_thread['locked'] == 0 || api_is_allowed_to_edit(false, true)
) {
@ -238,9 +255,17 @@ foreach ($rows as $post) {
'success',
['id' => "quote-post-{$post['post_id']}"]
);
if ($current_forum['moderated'] && !api_is_allowed_to_edit(false, true)) {
if (empty($post['status']) || $post['status'] == CForumPost::STATUS_WAITING_MODERATION) {
$buttonReply = '';
$buttonQuote = '';
}
}
}
}
} else {
$closedPost = '';
if ($current_forum_category && $current_forum_category['locked'] == 1) {
$closedPost = Display::tag(
'div',
@ -265,10 +290,8 @@ foreach ($rows as $post) {
$html .= $closedPost;
}
$html .= '</div>';
// note: this can be removed here because it will be displayed in the tree
if (
isset($whatsnew_post_info[$current_forum['forum_id']][$current_thread['thread_id']][$post['post_id']]) &&
@ -282,7 +305,8 @@ foreach ($rows as $post) {
if ($post['post_notification'] == '1' && $post['poster_id'] == $userId) {
$post_image .= Display::return_icon(
'forumnotification.gif', get_lang('YouWillBeNotified')
'forumnotification.gif',
get_lang('YouWillBeNotified')
);
}
@ -293,10 +317,8 @@ foreach ($rows as $post) {
$html .= Display::tag('div', $titlePost, array('class' => 'post-header'));
// the post body
$html .= Display::tag('div', $post['post_text'], array('class' => 'post-body'));
$html .= '</div>';
$html .= '</div>';
$html .= '<div class="row">';
@ -305,11 +327,10 @@ foreach ($rows as $post) {
$attachment_list = getAllAttachment($post['post_id']);
if (!empty($attachment_list) && is_array($attachment_list)) {
foreach ($attachment_list as $attachment) {
$realname = $attachment['path'];
$user_filename = $attachment['filename'];
$html .= Display::return_icon('attachment.gif', get_lang('Attachment'));
$html .= '<a href="download.php?file=';
$html .= $realname;
$html .= $attachment['path'];
$html .= ' "> ' . $user_filename . ' </a>';
$html .= '<span class="forum_attach_comment" >' . $attachment['comment'] . '</span>';
if (($current_forum['allow_edit'] == 1 && $post['user_id'] == $userId) ||
@ -326,18 +347,18 @@ foreach ($rows as $post) {
$html .= '</div>';
$html .= '<div class="col-md-6 text-right">';
$html .= $buttonReply . ' ' . $buttonQuote;
$html .= "$editButton $buttonReply $buttonQuote $waitingValidation";
$html .= '</div>';
$html .= '</div>';
// The post has been displayed => it can be removed from the what's new array
unset($whatsnew_post_info[$current_forum['forum_id']][$current_thread['thread_id']][$post['post_id']]);
unset($_SESSION['whatsnew_post_info'][$current_forum['forum_id']][$current_thread['thread_id']][$post['post_id']]);
$html .= '</div>';
$html .= '</div>';
$html .= '</div>';
echo $html;
echo $html;
$count++;
}

@ -1,6 +1,8 @@
<?php
/* For licensing terms, see /license.txt */
use Chamilo\CourseBundle\Entity\CForumPost;
/**
* Responses to AJAX calls for forum attachments
* @package chamilo/forum
@ -13,24 +15,21 @@ require_once api_get_path(SYS_CODE_PATH) . 'forum/forumfunction.inc.php';
// First, protect this script
api_protect_course_script(false);
/**
* Main code
*/
$action = isset($_REQUEST['a']) ? $_REQUEST['a'] : null;
// Create a default error response
$json = array(
'error' => true,
'errorMessage' => 'ERROR',
);
$action = isset($_REQUEST['a']) ? $_REQUEST['a'] : null;
$current_forum = get_forum_information($_REQUEST['forum']);
$current_forum_category = get_forumcategory_information($current_forum['forum_category']);
$current_thread = get_thread_information($_REQUEST['forum'], $_REQUEST['thread']);
// Check if exist action
if (!empty($action)) {
switch ($action) {
case 'upload_file':
$current_forum = get_forum_information($_REQUEST['forum']);
$current_forum_category = get_forumcategory_information($current_forum['forum_category']);
$current_thread = get_thread_information($_REQUEST['forum'], $_REQUEST['thread']);
if (!empty($_FILES) && !empty($_REQUEST['forum'])) {
// The user is not allowed here if
// 1. the forum category, forum or thread is invisible (visibility==0)
@ -95,8 +94,13 @@ if (!empty($action)) {
}
}
}
echo json_encode($json);
break;
case 'delete_file':
$current_forum = get_forum_information($_REQUEST['forum']);
$current_forum_category = get_forumcategory_information($current_forum['forum_category']);
$current_thread = get_thread_information($_REQUEST['forum'], $_REQUEST['thread']);
// Check if set attachment ID and thread ID
if (isset($_REQUEST['attachId']) && isset($_REQUEST['thread'])) {
api_block_course_item_locked_by_gradebook($_REQUEST['thread'], LINK_FORUM_THREAD);
@ -107,24 +111,24 @@ if (!empty($action)) {
// 4. if editing of replies is not allowed
// The only exception is the course manager
// They are several pieces for clarity.
if (!api_is_allowed_to_edit(null, true) AND
if (!api_is_allowed_to_edit(null, true) &&
(
($current_forum_category && $current_forum_category['visibility'] == 0) OR
($current_forum_category && $current_forum_category['visibility'] == 0) ||
$current_forum['visibility'] == 0)
) {
$json['errorMessage'] = '1. the forum category, forum or thread is invisible (visibility==0)';
break;
}
if (!api_is_allowed_to_edit(null, true) AND
if (!api_is_allowed_to_edit(null, true) &&
(
($current_forum_category && $current_forum_category['locked'] <> 0) OR
$current_forum['locked'] <> 0 OR $current_thread['locked'] <> 0
($current_forum_category && $current_forum_category['locked'] <> 0) ||
$current_forum['locked'] <> 0 || $current_thread['locked'] <> 0
)
) {
$json['errorMessage'] = '2. the forum category, forum or thread is locked (locked <>0)';
break;
}
if (api_is_anonymous() AND $current_forum['allow_anonymous'] == 0) {
if (api_is_anonymous() && $current_forum['allow_anonymous'] == 0) {
$json['errorMessage'] = '3. if anonymous posts are not allowed';
break;
}
@ -147,9 +151,52 @@ if (!empty($action)) {
$json['errorMessage'] = 'Success';
}
}
echo json_encode($json);
break;
case 'change_post_status':
if (api_is_allowed_to_edit(false, true)) {
$postId = isset($_GET['post_id']) ? $_GET['post_id'] : '';
if (empty($postId)) {
exit;
}
$postId = str_replace('status_post_', '', $postId);
$em = Database::getManager();
/** @var CForumPost $post */
$post = $em->find('ChamiloCourseBundle:CForumPost', $postId);
if ($post) {
$forum = get_forums($post->getForumId(), api_get_course_id());
$status = $post->getStatus();
if (empty($status)) {
$status = CForumPost::STATUS_WAITING_MODERATION;
}
switch ($status) {
case CForumPost::STATUS_VALIDATED:
$changeTo = CForumPost::STATUS_REJECTED;
break;
case CForumPost::STATUS_WAITING_MODERATION:
$changeTo = CForumPost::STATUS_VALIDATED;
break;
case CForumPost::STATUS_REJECTED:
$changeTo = CForumPost::STATUS_WAITING_MODERATION;
break;
}
$post->setStatus($changeTo);
$em->persist($post);
$em->flush();
echo getPostStatus(
$forum,
[
'iid' => $post->getIid(),
'status' => $post->getStatus(),
],
false
);
}
}
break;
}
}
echo json_encode($json);
exit;

@ -1988,10 +1988,25 @@ class Display
return $html;
}
/**
* @param array $buttons
* @return string
*/
public static function groupButton($buttons)
{
$html = '<div class="btn-group" role="group">';
foreach ($buttons as $button) {
$html .= $button;
}
$html .= '</div>';
return $html;
}
/**
* @todo use twig
*/
public static function group_button($title, $elements)
public static function groupButtonWithDropDown($title, $elements)
{
$html = '<div class="btn-group">
<button class="btn btn-default dropdown-toggle" data-toggle="dropdown">
@ -2337,6 +2352,8 @@ class Display
* @param string $icon The Awesome Font class for icon
* @param string $type Optional. The button Bootstrap class. Default 'default' class
* @param array $attributes The additional attributes
* @param bool $includeText
*
* @return string The button HTML
*/
public static function toolbarButton(
@ -2504,16 +2521,20 @@ HTML;
/**
* Returns the string "1 day ago" with a link showing the exact date time.
* @param string $dateTime in UTC
* @param string $dateTime in UTC or a DateTime in UTC
*
* @return string
*/
public static function dateToStringAgoAndLongDate($dateTime)
{
if (empty($dateTime) || $dateTime === '0000-00-00 00:00:00') {
if (empty($dateTime) || $dateTime === '0000-00-00 00:00:00') {
return '';
}
if ($dateTime instanceof \DateTime) {
$dateTime = $dateTime->format('Y-m-d H:i:s');
}
return self::tip(
date_to_str_ago($dateTime),
api_get_local_time($dateTime)

@ -7947,11 +7947,15 @@ $Unassigned = "Unassigned";
$SelectWeeksSpan = "Select the timespan in weeks";
$CourseXAdded = "Course %s added";
$CurrentPassword = "Current password";
$DeleteCorrections = "Delete corrections";
$DeleteCorrections = "Delete all corrections";
$AllowMyFilesTitle = "Enable 'My Files' section";
$AllowMyFilesComment = "Allow users to upload files to a personal space on the platform.";
$InstallMultiURLDetectedNotMainURL = "You are currently using the multi-URL feature and are trying to upgrade your portal using a secondary URL. Please connect to the main URL to proceed with the upgrade: %s";
$OnlyXQuestionsPickedRandomly = "Only %s questions will be picked randomly following the quiz configuration.";
$AllowDownloadDocumentsByApiKeyTitle = "Allow download course documents by API Key";
$AllowDownloadDocumentsByApiKeyComment = "Download documents verifying the REST API key for a user";
$UploadCorrectionsExplanationWithDownloadLinkX = "First you have to download the corrections <a href='%s'> here </a>.
After that you have to unzip that file and edit the files as you wanted without changing the file names.
Then create a zip file with those modified files and upload it in this form.";
$PostsPendingModeration = "Posts pending moderation";
?>

@ -5916,7 +5916,7 @@ class learnpath
])
),
);
$actionsRight = Display::group_button(get_lang('PrerequisitesOptions'), $buttons);
$actionsRight = Display::groupButtonWithDropDown(get_lang('PrerequisitesOptions'), $buttons);
}
$toolbar = Display::toolbarAction('actions-lp-controller', array($actionsLeft, $actionsRight));

Loading…
Cancel
Save