Admin: Add configuration setting 'allow_course_extra_field_in_catalog'

Add course extra fields filters in the course catalog BT#16817
pull/3159/head
Julio Montoya 6 years ago
parent 9b067fab04
commit bb78e5e303
  1. 350
      main/auth/courses.php
  2. 19
      main/auth/layout.php
  3. 5
      main/auth/sort_my_courses.php
  4. 421
      main/inc/lib/CoursesAndSessionsCatalog.class.php
  5. 97
      main/inc/lib/auth.lib.php
  6. 71
      main/inc/lib/course.lib.php
  7. 230
      main/inc/lib/course_category.lib.php
  8. 2677
      main/inc/lib/userportal.lib.php
  9. 3
      main/install/configuration.dist.php
  10. 29
      main/template/default/catalog/course_catalog.tpl
  11. 82
      main/template/default/catalog/course_item_catalog.tpl
  12. 1
      main/template/default/catalog/session_catalog.tpl

@ -17,14 +17,16 @@ $limit = CoursesAndSessionsCatalog::getLimitArray();
// Section for the tabs.
$this_section = SECTION_CATALOG;
if (api_get_setting('course_catalog_published') !== 'true') {
if ('true' !== api_get_setting('course_catalog_published')) {
// Access rights: anonymous users can't do anything useful here.
api_block_anonymous_users();
}
$allowExtraFields = api_get_configuration_value('allow_course_extra_field_in_catalog');
// For students
$userCanViewPage = true;
if (api_get_setting('allow_students_to_browse_courses') === 'false') {
if ('false' === api_get_setting('allow_students_to_browse_courses')) {
$userCanViewPage = false;
}
@ -35,7 +37,9 @@ if (api_is_platform_admin() || api_is_course_admin() || api_is_allowed_to_create
$defaultAction = CoursesAndSessionsCatalog::is(CATALOG_SESSIONS) ? 'display_sessions' : 'display_courses';
$action = isset($_REQUEST['action']) ? Security::remove_XSS($_REQUEST['action']) : $defaultAction;
$categoryCode = isset($_GET['category_code']) && !empty($_GET['category_code']) ? $_GET['category_code'] : 'ALL';
$categoryCode = isset($_REQUEST['category_code']) && !empty($_REQUEST['category_code']) ? Security::remove_XSS(
$_REQUEST['category_code']
) : 'ALL';
$searchTerm = isset($_REQUEST['search_term']) ? Security::remove_XSS($_REQUEST['search_term']) : '';
$nameTools = CourseCategory::getCourseCatalogNameTools($action);
@ -138,42 +142,129 @@ switch ($action) {
if (!$userCanViewPage) {
api_not_allowed(true);
}
$listCategories = CoursesAndSessionsCatalog::getCourseCategoriesTree();
$countCoursesInCategory = CourseCategory::countCoursesInCategory($categoryCode, $searchTerm);
if ($action === 'display_random_courses') {
$form = new FormValidator('search', 'get', '', null, null, FormValidator::LAYOUT_BOX);
$form->addHidden('action', 'search_course');
$form->addText('search_term', get_lang('Title'));
$jqueryReadyContent = '';
if ($allowExtraFields) {
$extraField = new ExtraField('course');
$returnParams = $extraField->addElements($form, null, [], true);
$jqueryReadyContent = $returnParams['jquery_ready_content'];
}
if ('display_random_courses' === $action) {
// Random value is used instead limit filter
$browse_courses_in_category = CoursesAndSessionsCatalog::getCoursesInCategory(null, 12);
$countCoursesInCategory = count($data['browse_courses_in_category']);
} elseif($action === 'search_course' && $categoryCode !== 'ALL') {
$browse_courses_in_category = CoursesAndSessionsCatalog::search_courses(
$searchTerm,
$limit
);
$countCoursesInCategory = CourseCategory::countCoursesInCategory('ALL', $searchTerm);
$courses = CoursesAndSessionsCatalog::getCoursesInCategory(null, 12);
$countCoursesInCategory = count($courses);
} elseif ('search_course' === $action) {
$values = $_REQUEST;
if (!empty($values) && $form->hasElement('extra_tags')) {
$tagElement = $form->getElement('extra_tags');
if (isset($values['extra_tags']) && !empty($values['extra_tags'])) {
$tags = [];
foreach ($values['extra_tags'] as $tag) {
$tag = Security::remove_XSS($tag);
$tags[] = $tag;
$tagElement->addOption(
$tag,
$tag
);
}
$form->setDefaults(
[
'extra_tags' => $tags,
]
);
}
}
$conditions = [];
$fields = [];
if ($allowExtraFields) {
// Parse params.
foreach ($values as $key => $value) {
if (substr($key, 0, 6) !== 'extra_' && substr($key, 0, 7) !== '_extra_') {
continue;
}
if (!empty($value)) {
$fields[$key] = $value;
}
}
$extraFields = $extraField->get_all(['visible_to_self = ? AND filter = ?' => [1, 1]], 'option_order');
$extraFields = array_column($extraFields, 'variable');
$filter = new stdClass();
foreach ($fields as $variable => $col) {
if (isset($values[$variable]) && !empty($values[$variable]) &&
in_array(str_replace('extra_', '', $variable), $extraFields)
) {
$rule = new stdClass();
$rule->field = $variable;
$rule->op = 'in';
$data = $col;
if (is_array($data) && array_key_exists($variable, $data)) {
$data = $col;
}
$rule->data = $data;
$filter->rules[] = $rule;
$filter->groupOp = 'AND';
}
}
$result = $extraField->getExtraFieldRules($filter);
$conditionArray = $result['condition_array'];
$whereCondition = '';
$extraCondition = '';
if (!empty($conditionArray)) {
$extraCondition = ' ( ';
$extraCondition .= implode(' AND ', $conditionArray);
$extraCondition .= ' ) ';
}
$whereCondition .= $extraCondition;
$options = ['where' => $whereCondition, 'extra' => $result['extra_fields']];
$conditions = $extraField->parseConditions($options, 'course');
}
$courses = CoursesAndSessionsCatalog::searchCourses($searchTerm, $limit, false, $conditions);
$countCoursesInCategory = CourseCategory::countCoursesInCategory('ALL', $searchTerm, true, $conditions);
} else {
if (!isset($categoryCode)) {
$categoryCode = $listCategories['ALL']['code']; // by default first category
}
$browse_courses_in_category = CoursesAndSessionsCatalog::getCoursesInCategory($categoryCode, null, $limit);
$courses = CoursesAndSessionsCatalog::getCoursesInCategory($categoryCode, null, $limit);
$countCoursesInCategory = CourseCategory::countCoursesInCategory($categoryCode, $searchTerm);
}
$list_categories = $listCategories;
$code = Security::remove_XSS($categoryCode);
$showCourses = CoursesAndSessionsCatalog::showCourses();
$showSessions = CoursesAndSessionsCatalog::showSessions();
$pageCurrent = isset($_GET['pageCurrent']) ? (int) $_GET['pageCurrent'] : 1;
$pageLength = isset($_GET['pageLength']) ? (int) $_GET['pageLength'] : CoursesAndSessionsCatalog::PAGE_LENGTH;
$pageTotal = (int) ceil($countCoursesInCategory / $pageLength);
$url = CoursesAndSessionsCatalog::getCatalogUrl(1, $pageLength, 'ALL', 0, 'search_course', $fields);
$form->setAttribute('action', $url);
// getting all the courses to which the user is subscribed to
$user_courses = $auth->get_courses_of_user($userId);
$user_courses = CourseManager::getCoursesByUserCourseCategory($userId);
$user_coursecodes = [];
// we need only the course codes as these will be used to match against the courses of the category
if ($user_courses != '') {
if ('' != $user_courses) {
foreach ($user_courses as $key => $value) {
$user_coursecodes[] = $value['code'];
}
}
if (api_is_drh()) {
$courses = CourseManager::get_courses_followed_by_drh($userId);
foreach ($courses as $course) {
$coursesDrh = CourseManager::get_courses_followed_by_drh($userId);
foreach ($coursesDrh as $course) {
$user_coursecodes[] = $course['code'];
}
}
@ -184,27 +275,22 @@ switch ($action) {
$catalogShowCoursesSessions = $showCoursesSessions;
}
$showCourses = CoursesAndSessionsCatalog::showCourses();
$showSessions = CoursesAndSessionsCatalog::showSessions();
$pageCurrent = isset($_GET['pageCurrent']) ? (int) $_GET['pageCurrent'] : 1;
$pageLength = isset($_GET['pageLength']) ? (int) $_GET['pageLength'] : CoursesAndSessionsCatalog::PAGE_LENGTH;
$pageTotal = (int) ceil($countCoursesInCategory / $pageLength);
$catalogPagination = '';
if ($pageTotal > 1) {
$catalogPagination = CourseCategory::getCatalogPagination(
$catalogPagination = CoursesAndSessionsCatalog::getCatalogPagination(
$pageCurrent,
$pageLength,
$pageTotal,
$categoryCode,
$action
$action,
$fields
);
}
$date = date('Y-m-d');
/*$date = date('Y-m-d');
if ($showSessions && isset($_POST['date'])) {
$date = $_POST['date'];
}
}*/
$userInfo = api_get_user_info();
$code = isset($code) ? $code : null;
$extraDate = '';
if ($showSessions) {
@ -246,32 +332,26 @@ switch ($action) {
<div class="row">';
if ($showCourses) {
$content .= '<div class="col-md-'.($showSessions ? '4' : '6').'">';
if (!isset($_GET['hidden_links']) || intval($_GET['hidden_links']) != 1) {
$content .= '
<form method="post"
action="'.CourseCategory::getCourseCategoryUrl(1, $pageLength, 'ALL', 0, 'search_course').'">
<input type="hidden" name="sec_token" value="'.$stok.'">
<label>'.get_lang('Search').'</label>
<div class="input-group">
<input class="form-control" type="text" name="search_term"
value="'.(empty($_POST['search_term']) ? '' : api_htmlentities($searchTerm)).'"/>
<div class="input-group-btn">
<button class="btn btn-default" type="submit">
<em class="fa fa-search"></em>'.get_lang('Search').'
</button>
</div>
</div>
</form>';
if (!isset($_GET['hidden_links']) || 1 != intval($_GET['hidden_links'])) {
$htmlHeadXtra[] = '<script>
$(function () {
'.$jqueryReadyContent.'
});
</script>';
$form->addButtonSearch(get_lang('Search'));
$content .= $form->returnForm();
}
$content .= '</div>';
$content .= '<div class="col-md-'.($showSessions ? '4' : '6').'">';
$listCategories = CoursesAndSessionsCatalog::getCourseCategoriesTree();
//$listCategories = CoursesAndSessionsCatalog::getCourseCategoriesTree();
$categoriesSelect = CoursesAndSessionsCatalog::getOptionSelect($listCategories, $categoryCode);
$webAction = api_get_path(WEB_CODE_PATH).'auth/courses.php';
$form = '<form action="'.$webAction.'" method="GET">';
$form .= '<input type="hidden" name="action" value="'.$action.'">';
$form .= '<input type="hidden" name="action" value="display_courses">';
$form .= '<input type="hidden" name="pageCurrent" value="'.$pageCurrent.'">';
$form .= '<input type="hidden" name="pageLength" value="'.$pageLength.'">';
$form .= '<div class="form-group">';
@ -287,10 +367,10 @@ switch ($action) {
if ($showCourses) {
if (!empty($searchTerm)) {
$content .= "<p><strong>".get_lang('SearchResultsFor')." ".$searchTerm."</strong><br />";
$content .= '<p><strong>'.get_lang('SearchResultsFor').' '.$searchTerm.'</strong><br />';
}
$showTeacher = api_get_setting('display_teacher_in_courselist') === 'true';
$showTeacher = 'true' === api_get_setting('display_teacher_in_courselist');
$ajax_url = api_get_path(WEB_AJAX_PATH).'course.ajax.php?a=add_course_vote';
$user_id = api_get_user_id();
$categoryListFromDatabase = CourseCategory::getAllCategories();
@ -302,121 +382,196 @@ switch ($action) {
}
}
if (!empty($browse_courses_in_category)) {
$content .= '<div class="grid-courses row">';
foreach ($browse_courses_in_category as $course) {
$course_hidden = $course['visibility'] == COURSE_VISIBILITY_HIDDEN;
if ($allowExtraFields) {
$extraFieldValues = new ExtraFieldValue('course');
$em = Database::getManager();
$fieldsRepo = $em->getRepository('ChamiloCoreBundle:ExtraField');
$fieldTagsRepo = $em->getRepository('ChamiloCoreBundle:ExtraFieldRelTag');
$tagField = $fieldsRepo->findOneBy(
[
'extraFieldType' => \Chamilo\CoreBundle\Entity\ExtraField::COURSE_FIELD_TYPE,
'variable' => 'tags',
]
);
}
if ($course_hidden) {
$courseUrl = api_get_path(WEB_COURSE_PATH);
$hideRating = api_get_configuration_value('hide_course_rating');
if (!empty($courses)) {
foreach ($courses as &$course) {
$courseId = $course['real_id'];
if (COURSE_VISIBILITY_HIDDEN == $course['visibility']) {
continue;
}
$courseTags = [];
if ($allowExtraFields && !is_null($tagField)) {
$courseTags = $fieldTagsRepo->getTags($tagField, $courseId);
}
$userRegisteredInCourse = CourseManager::is_user_subscribed_in_course($user_id, $course['code']);
$userRegisteredInCourseAsTeacher = CourseManager::is_course_teacher($user_id, $course['code']);
$userRegistered = $userRegisteredInCourse && $userRegisteredInCourseAsTeacher;
$course_public = $course['visibility'] == COURSE_VISIBILITY_OPEN_WORLD;
$course_open = $course['visibility'] == COURSE_VISIBILITY_OPEN_PLATFORM;
$course_private = $course['visibility'] == COURSE_VISIBILITY_REGISTERED;
$course_closed = $course['visibility'] == COURSE_VISIBILITY_CLOSED;
$course_subscribe_allowed = $course['subscribe'] == 1;
$course_unsubscribe_allowed = $course['unsubscribe'] == 1;
$course_public = COURSE_VISIBILITY_OPEN_WORLD == $course['visibility'];
$course_open = COURSE_VISIBILITY_OPEN_PLATFORM == $course['visibility'];
$course_private = COURSE_VISIBILITY_REGISTERED == $course['visibility'];
$courseClosed = COURSE_VISIBILITY_CLOSED == $course['visibility'];
$course_subscribe_allowed = 1 == $course['subscribe'];
$course_unsubscribe_allowed = 1 == $course['unsubscribe'];
$count_connections = $course['count_connections'];
$creation_date = substr($course['creation_date'], 0, 10);
// display the course bloc
$html = '<div class="col-xs-12 col-sm-6 col-md-4"><div class="items items-courses">';
$course['category_title'] = '';
if (isset($course['category'])) {
$course['category_title'] = isset($categoryList[$course['category']]) ? $categoryList[$course['category']] : '';
}
// Display thumbnail
$html .= CoursesAndSessionsCatalog::returnThumbnail($course, $userRegistered);
$course['thumbnail'] = CoursesAndSessionsCatalog::returnThumbnail($course);
$course['description_button'] = CourseManager::returnDescriptionButton($course);
$subscribeButton = CoursesAndSessionsCatalog::return_register_button(
$course,
$stok,
$categoryCode,
$searchTerm
);
$separator = null;
$subscribeButton = CoursesAndSessionsCatalog::return_register_button($course, $stok, $code, $searchTerm);
// Start buy course validation
// display the course price and buy button if the buycourses plugin is enabled and this course is configured
$plugin = BuyCoursesPlugin::create();
$isThisCourseInSale = $plugin->buyCoursesForGridCatalogValidator(
$course['real_id'],
$courseId,
BuyCoursesPlugin::PRODUCT_TYPE_COURSE
);
$separator = '';
if ($isThisCourseInSale) {
// set the Price label
$separator = $isThisCourseInSale['html'];
// set the Buy button instead register.
if ($isThisCourseInSale['verificator']) {
$subscribeButton = $plugin->returnBuyCourseButton(
$course['real_id'],
$courseId,
BuyCoursesPlugin::PRODUCT_TYPE_COURSE
);
}
}
// end buy course validation
// display course title and button bloc
$html .= '<div class="description">';
$html .= CoursesAndSessionsCatalog::return_title($course, $userRegisteredInCourse);
// end buy course validation
$course['title_formatted'] = CoursesAndSessionsCatalog::return_title($course, $userRegisteredInCourse);
$course['rating'] = '';
if ($hideRating === false) {
$ajax_url = api_get_path(WEB_AJAX_PATH).'course.ajax.php?a=add_course_vote';
$rating = Display::return_rating_system(
'star_'.$course['real_id'],
$ajax_url.'&course_id='.$course['real_id'],
$course['point_info']
);
$course['rating'] = '<div class="ranking">'.$rating.'</div>';
}
if ($showTeacher) {
$html .= CoursesAndSessionsCatalog::return_teacher($course);
$course['teacher_info'] = CoursesAndSessionsCatalog::return_teacher($course);
}
// display button line
$html .= '<div class="toolbar row">';
$html .= $separator ? '<div class="col-sm-4">'.$separator.'</div>' : '';
$html .= '<div class="col-sm-8">';
$course['buy_course'] = $separator;
if ($allowExtraFields) {
$course['extra_data'] = '';
$values = $extraFieldValues->getAllValuesForAnItem($courseId, true, true);
foreach ($values as $valueItem) {
/** @var \Chamilo\CoreBundle\Entity\ExtraFieldValues $value */
$value = $valueItem['value'];
if ($value) {
$data = $value->getValue();
if (!empty($data)) {
$course['extra_data'] .= $value->getField()->getDisplayText().': ';
switch ($value->getField()->getFieldType()) {
case ExtraField::FIELD_TYPE_CHECKBOX:
if ($value->getValue() == 1) {
$course['extra_data'] .= get_lang('Yes').'<br />';
} else {
$course['extra_data'] .= get_lang('No').'<br />';
}
break;
default:
$course['extra_data'] .= $value->getValue().'<br />';
break;
}
}
}
}
$course['extra_data_tags'] = [];
if (!empty($courseTags)) {
/** @var \Chamilo\CoreBundle\Entity\Tag $tag */
foreach ($courseTags as $tag) {
$tagUrl = Display::url($tag->getTag(), $url.'&extra_tags%5B%5D='.$tag->getTag());
$course['extra_data_tags'][] = $tagUrl;
}
}
}
// if user registered as student
if ($userRegisteredInCourse) {
$html .= CoursesAndSessionsCatalog::return_already_registered_label('student');
if (!$course_closed) {
$course['already_registered_formatted'] = Display::url(
Display::returnFontAwesomeIcon('external-link').'&nbsp;'.
get_lang('GoToCourse'),
$courseUrl.$course['directory'].'/index.php?id_session=0',
['class' => 'btn btn-primary']
);
if (!$courseClosed) {
if ($course_unsubscribe_allowed) {
$html .= CoursesAndSessionsCatalog::return_unregister_button($course, $stok, $searchTerm, $code);
$course['unregister_formatted'] = CoursesAndSessionsCatalog::return_unregister_button(
$course,
$stok,
$searchTerm,
$categoryCode
);
}
}
} elseif ($userRegisteredInCourseAsTeacher) {
// if user registered as teacher
if ($course_unsubscribe_allowed) {
$html .= CoursesAndSessionsCatalog::return_unregister_button($course, $stok, $searchTerm, $code);
$course['unregister_formatted'] = CoursesAndSessionsCatalog::return_unregister_button(
$course,
$stok,
$searchTerm,
$categoryCode
);
}
} else {
// if user not registered in the course
if (!$course_closed) {
if (!$courseClosed) {
if (!$course_private) {
if ($course_subscribe_allowed) {
$html .= $subscribeButton;
$course['subscribe_formatted'] = $subscribeButton;
}
}
}
}
$html .= '</div>';
$html .= '</div>';
$html .= '</div>';
$html .= '</div>';
$html .= '</div>';
$content .= $html;
}
$content .= '</div>';
} else {
if (!isset($_REQUEST['subscribe_user_with_password']) &&
!isset($_REQUEST['subscribe_course'])
) {
$content .= Display::return_message(
Display::addFlash(Display::return_message(
get_lang('ThereAreNoCoursesInThisCategory'),
'warning'
);
));
}
}
}
$content .= '<div class="col-md-12">';
$content .= $catalogPagination;
$content .= '</div>';
$template = new Template($toolTitle, true, true, false, false, false);
$template->assign('content', $content);
$template->assign('courses', $courses);
$template->assign('pagination', $catalogPagination);
$template->display($template->get_template('catalog/course_catalog.tpl'));
exit;
break;
case 'display_sessions':
if (!$userCanViewPage) {
@ -449,10 +604,9 @@ switch ($action) {
}
$registrationAllowed = api_get_setting('catalog_allow_session_auto_subscription');
if ($registrationAllowed === 'true') {
if ('true' === $registrationAllowed) {
$entityManager = Database::getManager();
$repository = $entityManager->getRepository('ChamiloCoreBundle:SequenceResource');
$sequences = $repository->getRequirements(
$sessionId,
SequenceResource::SESSION_TYPE
@ -487,7 +641,7 @@ switch ($action) {
if ($count <= 0) {
// no course in session -> return to catalog
$url = api_get_path(WEB_CODE_PATH).'auth/courses.php';
} elseif ($count == 1) {
} elseif (1 == $count) {
// only one course, so redirect directly to this course
foreach ($coursesList as $course) {
$url = api_get_path(WEB_COURSE_PATH).$course['directory'].'/index.php?id_session='.$sessionId;

@ -1,19 +0,0 @@
<?php
/* For licensing terms, see /license.txt */
/**
* Layout (principal view) used for structuring other views.
*
* @author Christian Fasanando <christian1827@gmail.com> - Beeznest
*
* @package chamilo.auth
*/
// Header
Display::display_header('');
// Display
echo $content;
// Footer
Display::display_footer();

@ -1,4 +1,5 @@
<?php
/* For licensing terms, see /license.txt */
$cidReset = true; // Flag forcing the 'current course' reset
@ -9,7 +10,7 @@ api_block_anonymous_users();
$auth = new Auth();
$user_course_categories = CourseManager::get_user_course_categories(api_get_user_id());
$courses_in_category = $auth->get_courses_in_category();
$courses_in_category = $auth->getCoursesInCategory();
$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : '';
$currentUrl = api_get_self();
@ -188,7 +189,7 @@ switch ($action) {
}
$table = Database::get_main_table(TABLE_USER_COURSE_CATEGORY);
$sql = "UPDATE $table
$sql = "UPDATE $table
SET collapsed = $option
WHERE user_id = $userId AND id = $categoryId";
Database::query($sql);

@ -181,7 +181,6 @@ class CoursesAndSessionsCatalog
];
$allCategories = CourseCategory::getAllCategories();
foreach ($allCategories as $category) {
if (empty($category['parent_id'])) {
$list[$category['code']] = $category;
@ -214,58 +213,7 @@ class CoursesAndSessionsCatalog
return array_merge($list, $categories);
}
/**
* @return array
*/
public static function getCourseCategories()
{
$urlId = 1;
if (api_is_multiple_url_enabled()) {
$urlId = api_get_current_access_url_id();
}
$countCourses = self::countAvailableCoursesToShowInCatalog($urlId);
$categories = [];
$categories[0][0] = [
'id' => 0,
'name' => get_lang('DisplayAll'),
'code' => 'ALL',
'parent_id' => null,
'tree_pos' => 0,
'count_courses' => $countCourses,
];
$categoriesFromDatabase = CourseCategory::getCategories();
foreach ($categoriesFromDatabase as $row) {
$countCourses = CourseCategory::countCoursesInCategory($row['code']);
$row['count_courses'] = $countCourses;
if (empty($row['parent_id'])) {
$categories[0][$row['tree_pos']] = $row;
} else {
$categories[$row['parent_id']][$row['tree_pos']] = $row;
}
}
// count courses that are in no category
$countCourses = CourseCategory::countCoursesInCategory();
$categories[0][count($categories[0]) + 1] = [
'id' => 0,
'name' => get_lang('None'),
'code' => 'NONE',
'parent_id' => null,
'tree_pos' => $row['tree_pos'] + 1,
'children_count' => 0,
'auth_course_child' => true,
'auth_cat_child' => true,
'count_courses' => $countCourses,
];
return $categories;
}
/**
/**
* Return LIMIT to filter SQL query.
*
* @param array $limit
@ -285,21 +233,21 @@ class CoursesAndSessionsCatalog
}
/**
* @param string $category_code
* @param int $random_value
* @param array $limit will be used if $random_value is not set.
* @param string $categoryCode
* @param int $randomValue
* @param array $limit will be used if $randomValue is not set.
* This array should contains 'start' and 'length' keys
*
* @return array
*/
public static function getCoursesInCategory($category_code, $random_value = null, $limit = [])
public static function getCoursesInCategory($categoryCode, $randomValue = null, $limit = [])
{
$tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
$avoidCoursesCondition = self::getAvoidCourseCondition();
$visibilityCondition = CourseManager::getCourseVisibilitySQLCondition('course', true);
if (!empty($random_value)) {
$random_value = (int) $random_value;
if (!empty($randomValue)) {
$randomValue = (int) $randomValue;
$sql = "SELECT COUNT(*) FROM $tbl_course";
$result = Database::query($sql);
@ -328,19 +276,19 @@ class CoursesAndSessionsCatalog
ON (url_rel_course.c_id = course.id)
WHERE
$urlCondition AND
RAND()*$num_records< $random_value
RAND()*$num_records< $randomValue
$avoidCoursesCondition
$visibilityCondition
ORDER BY RAND()
LIMIT 0, $random_value";
LIMIT 0, $randomValue";
} else {
$sql = "SELECT id, id as real_id FROM $tbl_course course
WHERE
RAND()*$num_records< $random_value
RAND()*$num_records< $randomValue
$avoidCoursesCondition
$visibilityCondition
ORDER BY RAND()
LIMIT 0, $random_value";
LIMIT 0, $randomValue";
}
$result = Database::query($sql);
@ -358,24 +306,24 @@ class CoursesAndSessionsCatalog
$sql = "SELECT *, id as real_id FROM $tbl_course WHERE id IN($id_in)";
} else {
$limitFilter = self::getLimitFilterFromArray($limit);
$category_code = Database::escape_string($category_code);
$listCode = self::childrenCategories($category_code);
$categoryCode = Database::escape_string($categoryCode);
$listCode = self::childrenCategories($categoryCode);
$conditionCode = ' ';
if (empty($listCode)) {
if ($category_code === 'NONE') {
if ($categoryCode === 'NONE') {
$conditionCode .= " category_code='' ";
} else {
$conditionCode .= " category_code='$category_code' ";
$conditionCode .= " category_code='$categoryCode' ";
}
} else {
foreach ($listCode as $code) {
$conditionCode .= " category_code='$code' OR ";
}
$conditionCode .= " category_code='$category_code' ";
$conditionCode .= " category_code='$categoryCode' ";
}
if (empty($category_code) || $category_code == 'ALL') {
if (empty($categoryCode) || $categoryCode == 'ALL') {
$sql = "SELECT *, id as real_id
FROM $tbl_course course
WHERE
@ -398,7 +346,7 @@ class CoursesAndSessionsCatalog
$tbl_url_rel_course = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
$urlCondition = ' access_url_id = '.$urlId.' ';
if ($category_code != 'ALL') {
if ($categoryCode !== 'ALL') {
$sql = "SELECT *, course.id real_id FROM $tbl_course as course
INNER JOIN $tbl_url_rel_course as url_rel_course
ON (url_rel_course.c_id = course.id)
@ -426,7 +374,7 @@ class CoursesAndSessionsCatalog
while ($row = Database::fetch_array($result)) {
$row['registration_code'] = !empty($row['registration_code']);
$count_users = CourseManager::get_users_count_in_course($row['code']);
$count_connections_last_month = Tracking::get_course_connections_count(
$connectionsLastMonth = Tracking::get_course_connections_count(
$row['id'],
0,
api_get_utc_datetime(time() - (30 * 86400))
@ -435,10 +383,10 @@ class CoursesAndSessionsCatalog
if ($row['tutor_name'] == '0') {
$row['tutor_name'] = get_lang('NoManager');
}
$point_info = CourseManager::get_course_ranking($row['id'], 0);
$courses[] = [
'real_id' => $row['real_id'],
'point_info' => $point_info,
'point_info' => CourseManager::get_course_ranking($row['id'], 0),
'code' => $row['code'],
'directory' => $row['directory'],
'visual_code' => $row['visual_code'],
@ -451,7 +399,7 @@ class CoursesAndSessionsCatalog
'visibility' => $row['visibility'],
'category' => $row['category_code'],
'count_users' => $count_users,
'count_connections' => $count_connections_last_month,
'count_connections' => $connectionsLastMonth,
];
}
@ -462,25 +410,43 @@ class CoursesAndSessionsCatalog
* Search the courses database for a course that matches the search term.
* The search is done on the code, title and tutor field of the course table.
*
* @param string $search_term The string that the user submitted, what we are looking for
* @param string $keyword The string that the user submitted
* @param array $limit
* @param bool $justVisible search only on visible courses in the catalogue
* @param array $conditions
*
* @return array an array containing a list of all the courses matching the the search term
*/
public static function search_courses($search_term, $limit, $justVisible = false)
public static function searchCourses($keyword, $limit, $justVisible = false, $conditions = [])
{
$courseTable = Database::get_main_table(TABLE_MAIN_COURSE);
$limitFilter = self::getLimitFilterFromArray($limit);
$avoidCoursesCondition = self::getAvoidCourseCondition();
$visibilityCondition = $justVisible ? CourseManager::getCourseVisibilitySQLCondition('course', true) : '';
$search_term_safe = Database::escape_string($search_term);
$sql = "SELECT * FROM $courseTable course
$visibilityCondition = $justVisible ? CourseManager::getCourseVisibilitySQLCondition('s', true) : '';
$keyword = Database::escape_string($keyword);
$sqlInjectJoins = '';
$where = ' 1 = 1 ';
$sqlInjectWhere = '';
$injectExtraFields = '1';
if (!empty($conditions)) {
$sqlInjectJoins = $conditions['inject_joins'];
$where = $conditions['where'];
$sqlInjectWhere = $conditions['inject_where'];
$injectExtraFields = !empty($conditions['inject_extra_fields']) ? $conditions['inject_extra_fields'] : 1;
$injectExtraFields = rtrim($injectExtraFields, ', ');
}
$sql = "SELECT DISTINCT course.*, $injectExtraFields
FROM $courseTable course
$sqlInjectJoins
WHERE (
course.code LIKE '%".$search_term_safe."%' OR
course.title LIKE '%".$search_term_safe."%' OR
course.tutor_name LIKE '%".$search_term_safe."%'
course.code LIKE '%".$keyword."%' OR
course.title LIKE '%".$keyword."%' OR
course.tutor_name LIKE '%".$keyword."%'
)
$where
$sqlInjectWhere
$avoidCoursesCondition
$visibilityCondition
ORDER BY title, visual_code ASC
@ -491,24 +457,26 @@ class CoursesAndSessionsCatalog
$urlId = api_get_current_access_url_id();
if ($urlId != -1) {
$tbl_url_rel_course = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
$urlCondition = ' access_url_id = '.$urlId.' AND';
$allowBaseCategories = api_get_configuration_value('allow_base_course_category');
if ($allowBaseCategories) {
$urlCondition = ' (access_url_id = '.$urlId.' OR access_url_id = 1) AND ';
}
$sql = "SELECT course.*
$sql = "SELECT DISTINCT course.*, $injectExtraFields
FROM $courseTable as course
INNER JOIN $tbl_url_rel_course as url_rel_course
ON (url_rel_course.c_id = course.id)
$sqlInjectJoins
WHERE
access_url_id = $urlId AND
(
code LIKE '%".$search_term_safe."%' OR
title LIKE '%".$search_term_safe."%' OR
tutor_name LIKE '%".$search_term_safe."%'
code LIKE '%".$keyword."%' OR
title LIKE '%".$keyword."%' OR
tutor_name LIKE '%".$keyword."%'
)
$where
$sqlInjectWhere
$avoidCoursesCondition
$visibilityCondition
ORDER BY title, visual_code ASC
@ -516,9 +484,9 @@ class CoursesAndSessionsCatalog
";
}
}
$result_find = Database::query($sql);
$result = Database::query($sql);
$courses = [];
while ($row = Database::fetch_array($result_find)) {
while ($row = Database::fetch_array($result)) {
$row['registration_code'] = !empty($row['registration_code']);
$countUsers = CourseManager::get_user_list_from_course_code(
$row['code'],
@ -534,11 +502,10 @@ class CoursesAndSessionsCatalog
api_get_utc_datetime(time() - (30 * 86400))
);
$point_info = CourseManager::get_course_ranking($row['id'], 0);
$ranking = CourseManager::get_course_ranking($row['id'], 0);
$courses[] = [
'real_id' => $row['id'],
'point_info' => $point_info,
'point_info' => $ranking,
'code' => $row['code'],
'directory' => $row['directory'],
'visual_code' => $row['visual_code'],
@ -626,12 +593,12 @@ class CoursesAndSessionsCatalog
if (!is_null($date)) {
$qb->andWhere(
$qb->expr()->orX(
$qb->expr()->isNull('s.accessEndDate'),
$qb->expr()->orX(
$qb->expr()->isNull('s.accessEndDate'),
$qb->expr()->andX(
$qb->expr()->isNotNull('s.accessStartDate'),
$qb->expr()->isNotNull('s.accessEndDate'),
$qb->expr()->lte('s.accessStartDate', $date),
$qb->expr()->lte('s.accessStartDate', $date),
$qb->expr()->gte('s.accessEndDate', $date)
),
$qb->expr()->andX(
@ -871,7 +838,7 @@ class CoursesAndSessionsCatalog
$list = [];
$row = [];
if ($code != 'ALL' and $code != 'NONE') {
if ($code !== 'ALL' and $code !== 'NONE') {
foreach ($allCategories as $category) {
if ($category['code'] === $code) {
$list = self::buildCourseCategoryTree($allCategories, $category['code'], 0);
@ -914,16 +881,11 @@ class CoursesAndSessionsCatalog
* Display the course catalog image of a course.
*
* @param array $course
* @param bool $registeredUser
*
* @return string HTML string
*/
public static function returnThumbnail($course, $registeredUser)
public static function returnThumbnail($course)
{
$html = '';
$title = cut($course['title'], 70);
$linkCourse = api_get_path(WEB_PATH).'course/'.$course['real_id'].'/about';
// course path
$course_path = api_get_path(SYS_COURSE_PATH).$course['directory'];
if (file_exists($course_path.'/course-pic.png')) {
@ -941,22 +903,7 @@ class CoursesAndSessionsCatalog
);
}
$html .= '<div class="image">';
$html .= '<a href="'.$linkCourse.'" title="'.$course['title'].'">'
.'<img class="img-responsive" src="'.$courseMediumImage.'" '
.'alt="'.api_htmlentities($title).'"/></a>';
$categoryTitle = isset($course['category_title']) ? $course['category_title'] : '';
if (!empty($categoryTitle)) {
$html .= '<span class="category">'.$categoryTitle.'</span>';
$html .= '<div class="cribbon"></div>';
}
$html .= '<div class="user-actions">';
$html .= CourseManager::returnDescriptionButton($course);
$html .= '</div></div>';
return $html;
return $courseMediumImage;
}
/**
@ -1022,43 +969,31 @@ class CoursesAndSessionsCatalog
* Display the title of a course in course catalog.
*
* @param array $course
* @param bool $registeredUser
*
* @return string HTML string
*/
public static function return_title($course, $registeredUser)
public static function return_title($course)
{
//$linkCourse = api_get_course_url($course['code']);
$linkCourse = api_get_path(WEB_PATH).'course/'.$course['real_id'].'/about';
$html = '<div class="block-title"><h4 class="title">';
$html .= '<a title="'.$course['title'].'" href="'.$linkCourse.'">'.$course['title'].'</a>';
$html .= '</h4></div>';
if (api_get_configuration_value('hide_course_rating') === false) {
$ajax_url = api_get_path(WEB_AJAX_PATH).'course.ajax.php?a=add_course_vote';
$rating = Display::return_rating_system(
'star_'.$course['real_id'],
$ajax_url.'&course_id='.$course['real_id'],
$course['point_info']
);
$html .= '<div class="ranking">'.$rating.'</div>';
}
return $html;
}
/**
* Display the already registerd text in a course in the course catalog.
*
* @param $in_status
* @param $status
*
* @return string HTML string
*/
public static function return_already_registered_label($in_status)
public static function return_already_registered_label($status)
{
$icon = '<em class="fa fa-check"></em>';
$title = get_lang('YouAreATeacherOfThisCourse');
if ($in_status == 'student') {
if ($status === 'student') {
$icon = '<em class="fa fa-check"></em>';
$title = get_lang('AlreadySubscribed');
}
@ -1082,12 +1017,12 @@ class CoursesAndSessionsCatalog
*
* @param $course
* @param $stok
* @param $code
* @param $categoryCode
* @param $search_term
*
* @return string
*/
public static function return_register_button($course, $stok, $code, $search_term)
public static function return_register_button($course, $stok, $categoryCode, $search_term)
{
$title = get_lang('Subscribe');
$action = 'subscribe_course';
@ -1098,7 +1033,7 @@ class CoursesAndSessionsCatalog
return Display::url(
Display::returnFontAwesomeIcon('check').' '.$title,
api_get_self().'?action='.$action.'&sec_token='.$stok.
'&course_code='.$course['code'].'&search_term='.$search_term.'&category_code='.$code,
'&course_code='.$course['code'].'&search_term='.$search_term.'&category_code='.$categoryCode,
['class' => 'btn btn-success btn-sm', 'title' => $title, 'aria-label' => $title]
);
}
@ -1109,19 +1044,19 @@ class CoursesAndSessionsCatalog
* @param $course
* @param $stok
* @param $search_term
* @param $code
* @param $categoryCode
*
* @return string
*/
public static function return_unregister_button($course, $stok, $search_term, $code)
public static function return_unregister_button($course, $stok, $search_term, $categoryCode)
{
$title = get_lang('Unsubscription');
return Display::url(
Display::returnFontAwesomeIcon('sign-in').' '.$title,
Display::returnFontAwesomeIcon('sign-in').'&nbsp;'.$title,
api_get_self().'?action=unsubscribe&sec_token='.$stok
.'&course_code='.$course['code'].'&search_term='.$search_term.'&category_code='.$code,
['class' => 'btn btn-danger btn-sm', 'title' => $title, 'aria-label' => $title]
.'&course_code='.$course['code'].'&search_term='.$search_term.'&category_code='.$categoryCode,
['class' => 'btn btn-danger', 'title' => $title, 'aria-label' => $title]
);
}
@ -1296,11 +1231,11 @@ class CoursesAndSessionsCatalog
$pageTotal = ceil($countSessions / $limit['length']);
// Do NOT show pagination if only one page or less
$pagination = $pageTotal > 1 ? CourseCategory::getCatalogPagination($limit['current'], $limit['length'], $pageTotal) : '';
$pagination = $pageTotal > 1 ? self::getCatalogPagination($limit['current'], $limit['length'], $pageTotal) : '';
$sessionsBlocks = self::getFormattedSessionsBlock($sessions);
// Get session search catalogue URL
$courseUrl = CourseCategory::getCourseCategoryUrl(
$courseUrl = self::getCatalogUrl(
1,
$limit['length'],
null,
@ -1323,7 +1258,7 @@ class CoursesAndSessionsCatalog
$tpl->assign('already_subscribed_label', self::getAlreadyRegisteredInSessionLabel());
$tpl->assign('catalog_settings', self::getCatalogSearchSettings());
$contentTemplate = $tpl->get_template('auth/session_catalog.tpl');
$contentTemplate = $tpl->get_template('catalog/session_catalog.tpl');
$tpl->display($contentTemplate);
}
@ -1337,7 +1272,7 @@ class CoursesAndSessionsCatalog
{
$keyword = isset($_POST['keyword']) ? $_POST['keyword'] : null;
$hiddenLinks = isset($_GET['hidden_links']) ? (int) $_GET['hidden_links'] == 1 : false;
$courseUrl = CourseCategory::getCourseCategoryUrl(
$courseUrl = self::getCatalogUrl(
1,
$limit['length'],
null,
@ -1361,7 +1296,7 @@ class CoursesAndSessionsCatalog
$tpl->assign('sessions', $sessionsBlocks);
$tpl->assign('catalog_settings', self::getCatalogSearchSettings());
$contentTemplate = $tpl->get_template('auth/session_catalog.tpl');
$contentTemplate = $tpl->get_template('catalog/session_catalog.tpl');
$tpl->display($contentTemplate);
}
@ -1394,7 +1329,7 @@ class CoursesAndSessionsCatalog
{
$pageLength = isset($_GET['pageLength']) ? (int) $_GET['pageLength'] : self::PAGE_LENGTH;
$url = CourseCategory::getCourseCategoryUrl(1, $pageLength, null, 0, 'display_sessions');
$url = self::getCatalogUrl(1, $pageLength, null, 0, 'display_sessions');
$headers = [];
if (self::showCourses()) {
$headers[] = [
@ -1423,7 +1358,7 @@ class CoursesAndSessionsCatalog
$searchTag = isset($_POST['search_tag']) ? $_POST['search_tag'] : null;
$searchDate = isset($_POST['date']) ? $_POST['date'] : date('Y-m-d');
$hiddenLinks = isset($_GET['hidden_links']) ? (int) $_GET['hidden_links'] == 1 : false;
$courseUrl = CourseCategory::getCourseCategoryUrl(
$courseUrl = self::getCatalogUrl(
1,
$limit['length'],
null,
@ -1446,7 +1381,7 @@ class CoursesAndSessionsCatalog
$tpl->assign('search_tag', Security::remove_XSS($searchTag));
$tpl->assign('sessions', $sessionsBlocks);
$contentTemplate = $tpl->get_template('auth/session_catalog.tpl');
$contentTemplate = $tpl->get_template('catalog/session_catalog.tpl');
$tpl->display($contentTemplate);
}
@ -1603,4 +1538,190 @@ class CoursesAndSessionsCatalog
return $sessionsBlocks;
}
/**
* Get Pagination HTML div.
*
* @param int $pageCurrent
* @param int $pageLength
* @param int $pageTotal
* @param string $categoryCode
* @param string $action
* @param array $fields
*
* @return string
*/
public static function getCatalogPagination($pageCurrent, $pageLength, $pageTotal, $categoryCode = '', $action = '', $fields = [])
{
// Start empty html
$pageDiv = '';
$html = '';
$pageBottom = max(1, $pageCurrent - 3);
$pageTop = min($pageTotal, $pageCurrent + 3);
if ($pageBottom > 1) {
$pageDiv .= self::getPageNumberItem(1, $pageLength);
if ($pageBottom > 2) {
$pageDiv .= self::getPageNumberItem(
$pageBottom - 1,
$pageLength,
null,
'...',
$categoryCode,
$action,
$fields
);
}
}
// For each page add its page button to html
for ($i = $pageBottom; $i <= $pageTop; $i++) {
if ($i === $pageCurrent) {
$pageItemAttributes = ['class' => 'active'];
} else {
$pageItemAttributes = [];
}
$pageDiv .= self::getPageNumberItem(
$i,
$pageLength,
$pageItemAttributes,
'',
$categoryCode,
$action,
$fields
);
}
// Check if current page is the last page
if ($pageTop < $pageTotal) {
if ($pageTop < ($pageTotal - 1)) {
$pageDiv .= self::getPageNumberItem(
$pageTop + 1,
$pageLength,
null,
'...',
$categoryCode,
$action,
$fields
);
}
$pageDiv .= self::getPageNumberItem($pageTotal, $pageLength, [], '', $categoryCode, $action, $fields);
}
// Complete pagination html
$pageDiv = Display::tag('ul', $pageDiv, ['class' => 'pagination']);
$html .= '<nav>'.$pageDiv.'</nav>';
return $html;
}
/**
* Get li HTML of page number.
*
* @param $pageNumber
* @param $pageLength
* @param array $liAttributes
* @param string $content
* @param string $categoryCode
* @param string $action
* @param array $fields
*
* @return string
*/
public static function getPageNumberItem(
$pageNumber,
$pageLength,
$liAttributes = [],
$content = '',
$categoryCode = '',
$action = '',
$fields = []
) {
// Get page URL
$url = self::getCatalogUrl($pageNumber, $pageLength, $categoryCode, null, $action, $fields);
// If is current page ('active' class) clear URL
if (isset($liAttributes) && is_array($liAttributes) && isset($liAttributes['class'])) {
if (strpos('active', $liAttributes['class']) !== false) {
$url = '';
}
}
$content = !empty($content) ? $content : $pageNumber;
return Display::tag(
'li',
Display::url(
$content,
$url
),
$liAttributes
);
}
/**
* Return URL to course catalog.
*
* @param int $pageCurrent
* @param int $pageLength
* @param string $categoryCode
* @param int $hiddenLinks
* @param string $action
*
* @return string
*/
public static function getCatalogUrl(
$pageCurrent,
$pageLength,
$categoryCode = null,
$hiddenLinks = null,
$action = null,
$extraFields = []
) {
$requestAction = isset($_REQUEST['action']) ? Security::remove_XSS($_REQUEST['action']) : null;
$action = isset($action) ? Security::remove_XSS($action) : $requestAction;
$searchTerm = isset($_REQUEST['search_term']) ? Security::remove_XSS($_REQUEST['search_term']) : null;
if ($action === 'subscribe_user_with_password') {
$action = 'subscribe';
}
$categoryCodeRequest = isset($_REQUEST['category_code']) ? Security::remove_XSS($_REQUEST['category_code']) : null;
$categoryCode = !empty($categoryCode) ? Security::remove_XSS($categoryCode) : $categoryCodeRequest;
$hiddenLinksRequest = !empty($_REQUEST['hidden_links']) ? Security::remove_XSS($_REQUEST['hidden_links']) : null;
$hiddenLinks = !empty($hiddenLinks) ? Security::remove_XSS($hiddenLinksRequest) : $categoryCodeRequest;
// Start URL with params
$pageUrl = api_get_self().
'?action='.$action.
'&category_code='.$categoryCode.
'&hidden_links='.$hiddenLinks.
'&pageCurrent='.$pageCurrent.
'&pageLength='.$pageLength;
if (!empty($extraFields)) {
$params = [];
foreach ($extraFields as $variable => $value) {
$params[Security::remove_XSS($variable)] = Security::remove_XSS($value);
}
if (!empty($params)) {
$pageUrl .= '&'.http_build_query($params);
}
}
switch ($action) {
case 'subscribe':
// for search
$pageUrl .=
'&search_term='.$searchTerm.
'&sec_token='.Security::getTokenFromSession();
break;
case 'display_courses':
default:
break;
}
return $pageUrl;
}
}

@ -19,72 +19,12 @@ class Auth
{
}
/**
* retrieves all the courses that the user has already subscribed to.
*
* @param int $user_id
*
* @return array an array containing all the information of the courses of the given user
*/
public function get_courses_of_user($user_id)
{
$TABLECOURS = Database::get_main_table(TABLE_MAIN_COURSE);
$TABLECOURSUSER = Database::get_main_table(TABLE_MAIN_COURSE_USER);
$avoidCoursesCondition = CoursesAndSessionsCatalog::getAvoidCourseCondition();
$visibilityCondition = CourseManager::getCourseVisibilitySQLCondition('course', true);
// Secondly we select the courses that are in a category (user_course_cat<>0) and
// sort these according to the sort of the category
$user_id = (int) $user_id;
$sql = "SELECT
course.code k,
course.visual_code vc,
course.subscribe subscr,
course.unsubscribe unsubscr,
course.title i,
course.tutor_name t,
course.category_code cat,
course.directory dir,
course_rel_user.status status,
course_rel_user.sort sort,
course_rel_user.user_course_cat user_course_cat
FROM $TABLECOURS course, $TABLECOURSUSER course_rel_user
WHERE
course.id = course_rel_user.c_id AND
course_rel_user.relation_type <> ".COURSE_RELATION_TYPE_RRHH." AND
course_rel_user.user_id = '".$user_id."'
$avoidCoursesCondition
$visibilityCondition
ORDER BY course_rel_user.sort ASC";
$result = Database::query($sql);
$courses = [];
while ($row = Database::fetch_array($result)) {
//we only need the database name of the course
$courses[] = [
'code' => $row['k'],
'visual_code' => $row['vc'],
'title' => $row['i'],
'directory' => $row['dir'],
'status' => $row['status'],
'tutor' => $row['t'],
'subscribe' => $row['subscr'],
'category' => $row['cat'],
'unsubscribe' => $row['unsubscr'],
'sort' => $row['sort'],
'user_course_category' => $row['user_course_cat'],
];
}
return $courses;
}
/**
* This function get all the courses in the particular user category.
*
* @return array
*/
public function get_courses_in_category()
public function getCoursesInCategory()
{
$user_id = api_get_user_id();
@ -122,7 +62,7 @@ class Auth
* (moving a course to a different course category).
*
* @param int $courseId
* @param int Category id
* @param int Category id
*
* @return bool True if it success
*/
@ -154,9 +94,9 @@ class Auth
/**
* moves the course one place up or down.
*
* @param string Direction (up/down)
* @param string Course code
* @param int Category id
* @param string Direction (up/down)
* @param string Course code
* @param int Category id
*
* @return bool True if it success
*/
@ -166,7 +106,7 @@ class Auth
$table = Database::get_main_table(TABLE_MAIN_COURSE_USER);
$current_user_id = api_get_user_id();
$all_user_courses = $this->get_courses_of_user($current_user_id);
$all_user_courses = $this->getCoursesOfUser($current_user_id);
// we need only the courses of the category we are moving in
$user_courses = [];
@ -227,7 +167,7 @@ class Auth
/**
* Moves the course one place up or down.
*
* @param string $direction Direction up/down
* @param string $direction Direction up/down
* @param string $category2move Category id
*
* @return bool True If it success
@ -235,7 +175,7 @@ class Auth
public function move_category($direction, $category2move)
{
$userId = api_get_user_id();
$userCategories = CourseManager::get_user_course_categories(api_get_user_id());
$userCategories = CourseManager::get_user_course_categories($userId);
$categories = array_values($userCategories);
$previous = null;
@ -246,7 +186,7 @@ class Auth
// source_course is the course where we clicked the up or down icon
$source_category = $userCategories[$category2move];
// target_course is the course before/after the source_course (depending on the up/down icon)
if ($direction == 'up') {
if ($direction === 'up') {
if (isset($categories[$key - 1])) {
$target_category = $userCategories[$categories[$key - 1]['id']];
}
@ -280,8 +220,8 @@ class Auth
/**
* Updates the user course category in the chamilo_user database.
*
* @param string Category title
* @param int Category id
* @param string Category title
* @param int Category id
*
* @return bool True if it success
*/
@ -305,7 +245,7 @@ class Auth
/**
* deletes a course category and moves all the courses that were in this category to main category.
*
* @param int Category id
* @param int Category id
*
* @return bool True if it success
*/
@ -396,7 +336,7 @@ class Auth
/**
* stores the user course category in the chamilo_user database.
*
* @param string Category title
* @param string Category title
*
* @return bool True if it success
*/
@ -407,7 +347,6 @@ class Auth
// protect data
$current_user_id = api_get_user_id();
$category_title = Database::escape_string($category_title);
$result = false;
// step 1: we determine the max value of the user defined course categories
$sql = "SELECT sort FROM $table
@ -425,15 +364,19 @@ class Auth
title='".$category_title."'
ORDER BY sort DESC";
$rs = Database::query($sql);
$result = false;
if (Database::num_rows($rs) == 0) {
$sql = "INSERT INTO $table (user_id, title,sort)
VALUES ('".$current_user_id."', '".api_htmlentities($category_title, ENT_QUOTES, api_get_system_encoding())."', '".$nextsort."')";
VALUES ('".$current_user_id."', '".api_htmlentities(
$category_title,
ENT_QUOTES,
api_get_system_encoding()
)."', '".$nextsort."')";
$resultQuery = Database::query($sql);
if (Database::affected_rows($resultQuery)) {
$result = true;
}
} else {
$result = false;
}
return $result;

@ -22,8 +22,6 @@ use ChamiloSession as Session;
* but not available in standard Chamilo).
*
* There are probably some places left with the wrong code.
*
* @package chamilo.library
*/
class CourseManager
{
@ -2911,7 +2909,7 @@ class CourseManager
*
* @return array Course codes allowed or not to see in catalogue by some user or the user
*/
public static function getCatalogueCourseList($allowed = true, $byUserId = -1)
public static function getCatalogCourseList($allowed = true, $byUserId = -1)
{
$courseTable = Database::get_main_table(TABLE_MAIN_COURSE);
$tblCourseRelUserCatalogue = Database::get_main_table(TABLE_MAIN_COURSE_CATALOGUE_USER);
@ -5257,16 +5255,16 @@ class CourseManager
// Check if course have users allowed to see it in the catalogue, then show only if current user is allowed to see it
$currentUserId = api_get_user_id();
$restrictedCourses = self::getCatalogueCourseList(true);
$allowedCoursesToCurrentUser = self::getCatalogueCourseList(true, $currentUserId);
$restrictedCourses = self::getCatalogCourseList(true);
$allowedCoursesToCurrentUser = self::getCatalogCourseList(true, $currentUserId);
if (!empty($restrictedCourses)) {
$visibilityCondition .= ' AND ('.$courseTableAlias.'.code NOT IN ("'.implode('","', $restrictedCourses).'")';
$visibilityCondition .= ' OR '.$courseTableAlias.'.code IN ("'.implode('","', $allowedCoursesToCurrentUser).'"))';
}
// Check if course have users denied to see it in the catalogue, then show only if current user is not denied to see it
$restrictedCourses = self::getCatalogueCourseList(false);
$notAllowedCoursesToCurrentUser = self::getCatalogueCourseList(false, $currentUserId);
$restrictedCourses = self::getCatalogCourseList(false);
$notAllowedCoursesToCurrentUser = self::getCatalogCourseList(false, $currentUserId);
if (!empty($restrictedCourses)) {
$visibilityCondition .= ' AND ('.$courseTableAlias.'.code NOT IN ("'.implode('","', $restrictedCourses).'")';
$visibilityCondition .= ' OR '.$courseTableAlias.'.code NOT IN ("'.implode('","', $notAllowedCoursesToCurrentUser).'"))';
@ -6715,4 +6713,63 @@ class CourseManager
$courseFieldValue = new ExtraFieldValue('course');
$courseFieldValue->saveFieldValues($params);
}
/**
* retrieves all the courses that the user has already subscribed to.
*
* @param int $user_id
*
* @return array an array containing all the information of the courses of the given user
*/
public static function getCoursesByUserCourseCategory($user_id)
{
$course = Database::get_main_table(TABLE_MAIN_COURSE);
$courseRelUser = Database::get_main_table(TABLE_MAIN_COURSE_USER);
$avoidCoursesCondition = CoursesAndSessionsCatalog::getAvoidCourseCondition();
$visibilityCondition = self::getCourseVisibilitySQLCondition('course', true);
// Secondly we select the courses that are in a category (user_course_cat<>0) and
// sort these according to the sort of the category
$user_id = (int) $user_id;
$sql = "SELECT
course.code k,
course.visual_code vc,
course.subscribe subscr,
course.unsubscribe unsubscr,
course.title i,
course.tutor_name t,
course.category_code cat,
course.directory dir,
course_rel_user.status status,
course_rel_user.sort sort,
course_rel_user.user_course_cat user_course_cat
FROM $course course, $courseRelUser course_rel_user
WHERE
course.id = course_rel_user.c_id AND
course_rel_user.relation_type <> ".COURSE_RELATION_TYPE_RRHH." AND
course_rel_user.user_id = '".$user_id."'
$avoidCoursesCondition
$visibilityCondition
ORDER BY course_rel_user.sort ASC";
$result = Database::query($sql);
$courses = [];
while ($row = Database::fetch_array($result, 'ASOC')) {
$courses[] = [
'code' => $row['k'],
'visual_code' => $row['vc'],
'title' => $row['i'],
'directory' => $row['dir'],
'status' => $row['status'],
'tutor' => $row['t'],
'subscribe' => $row['subscr'],
'category' => $row['cat'],
'unsubscribe' => $row['unsubscr'],
'sort' => $row['sort'],
'user_course_category' => $row['user_course_cat'],
];
}
return $courses;
}
}

@ -377,35 +377,6 @@ class CourseCategory
return true;
}
/**
* Counts the number of children categories a category has.
*
* @param int $categoryId The ID of the category of which we want to count the children
*
* @return mixed The number of subcategories this category has
*/
public static function courseCategoryChildrenCount($categoryId)
{
$table = Database::get_main_table(TABLE_MAIN_CATEGORY);
$categoryId = (int) $categoryId;
$count = 0;
if (empty($categoryId)) {
return 0;
}
$sql = "SELECT id, code FROM $table
WHERE parent_id = $categoryId";
$result = Database::query($sql);
while ($row = Database::fetch_array($result)) {
$count += self::courseCategoryChildrenCount($row['id']);
}
$sql = "UPDATE $table SET
children_count = $count
WHERE id = $categoryId";
Database::query($sql);
return $count + 1;
}
/**
* @param string $categoryCode
*
@ -472,9 +443,8 @@ class CourseCategory
foreach ($parents as $category) {
$categories[] = $category['code'];
}
$categoriesInString = implode(' > ', $categories).' > ';
return $categoriesInString;
return implode(' > ', $categories).' > ';
}
return null;
@ -568,9 +538,9 @@ class CourseCategory
}
return $table->toHtml();
} else {
return Display::return_message(get_lang('NoCategories'), 'warning');
}
return Display::return_message(get_lang('NoCategories'), 'warning');
}
/**
@ -619,14 +589,15 @@ class CourseCategory
* @param string $category_code
* @param string $searchTerm
* @paran bool $avoidCourses
* @paran array $conditions
*
* @return int
*/
public static function countCoursesInCategory($category_code = '', $searchTerm = '', $avoidCourses = true)
public static function countCoursesInCategory($category_code = '', $keyword = '', $avoidCourses = true, $conditions = [])
{
$tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
$categoryCode = Database::escape_string($category_code);
$searchTerm = Database::escape_string($searchTerm);
$keyword = Database::escape_string($keyword);
$avoidCoursesCondition = '';
if ($avoidCourses) {
@ -635,6 +606,15 @@ class CourseCategory
$visibilityCondition = CourseManager::getCourseVisibilitySQLCondition('course', true);
$sqlInjectJoins = '';
$where = ' AND 1 = 1 ';
$sqlInjectWhere = '';
if (!empty($conditions)) {
$sqlInjectJoins = $conditions['inject_joins'];
$where = $conditions['where'];
$sqlInjectWhere = $conditions['inject_where'];
}
$categoryFilter = '';
if ($categoryCode === 'ALL') {
// Nothing to do
@ -645,20 +625,21 @@ class CourseCategory
}
$searchFilter = '';
if (!empty($searchTerm)) {
if (!empty($keyword)) {
$searchFilter = ' AND (
code LIKE "%'.$searchTerm.'%" OR
title LIKE "%'.$searchTerm.'%" OR
tutor_name LIKE "%'.$searchTerm.'%"
code LIKE "%'.$keyword.'%" OR
title LIKE "%'.$keyword.'%" OR
tutor_name LIKE "%'.$keyword.'%"
) ';
}
$urlCondition = ' access_url_id = '.api_get_current_access_url_id().' AND';
$tbl_url_rel_course = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
$sql = "SELECT count(*) as count
$sql = "SELECT count(DISTINCT course.id) as count
FROM $tbl_course as course
INNER JOIN $tbl_url_rel_course as url_rel_course
ON (url_rel_course.c_id = course.id)
$sqlInjectJoins
WHERE
$urlCondition
course.visibility != '0' AND
@ -667,6 +648,8 @@ class CourseCategory
$searchFilter
$avoidCoursesCondition
$visibilityCondition
$where
$sqlInjectWhere
";
$result = Database::query($sql);
@ -737,173 +720,6 @@ class CourseCategory
return Database::store_result($result, 'ASSOC');
}
/**
* Get Pagination HTML div.
*
* @param $pageCurrent
* @param $pageLength
* @param $pageTotal
* @param $categoryCode
* @param $action
*
* @return string
*/
public static function getCatalogPagination($pageCurrent, $pageLength, $pageTotal, $categoryCode = '', $action = '')
{
// Start empty html
$pageDiv = '';
$html = '';
$pageBottom = max(1, $pageCurrent - 3);
$pageTop = min($pageTotal, $pageCurrent + 3);
if ($pageBottom > 1) {
$pageDiv .= self::getPageNumberItem(1, $pageLength);
if ($pageBottom > 2) {
$pageDiv .= self::getPageNumberItem(
$pageBottom - 1,
$pageLength,
null,
'...',
$categoryCode,
$action
);
}
}
// For each page add its page button to html
for ($i = $pageBottom; $i <= $pageTop; $i++) {
if ($i === $pageCurrent) {
$pageItemAttributes = ['class' => 'active'];
} else {
$pageItemAttributes = [];
}
$pageDiv .= self::getPageNumberItem(
$i,
$pageLength,
$pageItemAttributes,
'',
$categoryCode,
$action
);
}
// Check if current page is the last page
if ($pageTop < $pageTotal) {
if ($pageTop < ($pageTotal - 1)) {
$pageDiv .= self::getPageNumberItem(
$pageTop + 1,
$pageLength,
null,
'...',
$categoryCode,
$action
);
}
$pageDiv .= self::getPageNumberItem($pageTotal, $pageLength, [], '', $categoryCode, $action);
}
// Complete pagination html
$pageDiv = Display::tag('ul', $pageDiv, ['class' => 'pagination']);
$html .= '<nav>'.$pageDiv.'</nav>';
return $html;
}
/**
* Return URL to course catalog.
*
* @param int $pageCurrent
* @param int $pageLength
* @param string $categoryCode
* @param int $hiddenLinks
* @param string $action
*
* @return string
*/
public static function getCourseCategoryUrl(
$pageCurrent,
$pageLength,
$categoryCode = null,
$hiddenLinks = null,
$action = null
) {
$requestAction = isset($_REQUEST['action']) ? Security::remove_XSS($_REQUEST['action']) : null;
$action = isset($action) ? Security::remove_XSS($action) : $requestAction;
$searchTerm = isset($_REQUEST['search_term']) ? Security::remove_XSS($_REQUEST['search_term']) : null;
if ($action === 'subscribe_user_with_password') {
$action = 'subscribe';
}
$categoryCodeRequest = isset($_REQUEST['category_code']) ? Security::remove_XSS($_REQUEST['category_code']) : null;
$categoryCode = !empty($categoryCode) ? Security::remove_XSS($categoryCode) : $categoryCodeRequest;
$hiddenLinksRequest = !empty($_REQUEST['hidden_links']) ? Security::remove_XSS($_REQUEST['hidden_links']) : null;
$hiddenLinks = !empty($hiddenLinks) ? Security::remove_XSS($hiddenLinksRequest) : $categoryCodeRequest;
// Start URL with params
$pageUrl = api_get_self().
'?action='.$action.
'&category_code='.$categoryCode.
'&hidden_links='.$hiddenLinks.
'&pageCurrent='.$pageCurrent.
'&pageLength='.$pageLength;
switch ($action) {
case 'subscribe':
// for search
$pageUrl .=
'&search_term='.$searchTerm.
'&search_course=1'.
'&sec_token='.Security::getTokenFromSession();
break;
case 'display_courses':
default:
break;
}
return $pageUrl;
}
/**
* Get li HTML of page number.
*
* @param $pageNumber
* @param $pageLength
* @param array $liAttributes
* @param string $content
*
* @return string
*/
public static function getPageNumberItem(
$pageNumber,
$pageLength,
$liAttributes = [],
$content = '',
$categoryCode = '',
$action = ''
) {
// Get page URL
$url = self::getCourseCategoryUrl($pageNumber, $pageLength, $categoryCode, null, $action);
// If is current page ('active' class) clear URL
if (isset($liAttributes) && is_array($liAttributes) && isset($liAttributes['class'])) {
if (strpos('active', $liAttributes['class']) !== false) {
$url = '';
}
}
$content = !empty($content) ? $content : $pageNumber;
return Display::tag(
'li',
Display::url(
$content,
$url
),
$liAttributes
);
}
/**
* Return the name tool by action.
*

File diff suppressed because it is too large Load Diff

@ -1425,6 +1425,9 @@ ALTER TABLE notification_event ADD COLUMN event_id INT NULL;
// Course chat: Send message on button click only, if false then send on enter too.
//$_configuration['course_chat_send_message_only_on_button'] = true;
// Course catalog show extra fields (visible and filtered)
//$_configuration['allow_course_extra_field_in_catalog'] = false;
// KEEP THIS AT THE END
// -------- Custom DB changes
// Add user activation by confirmation email

@ -0,0 +1,29 @@
{% extends 'layout/layout_1_col.tpl'|get_template %}
{% block content %}
{{ content }}
<style>
/* WIP: To be move in base.css */
.search-courses .form-inline-box .input-group {
width: 80%;
padding-bottom: 14px;
}
.search-courses .form-inline-box .input-group label {
margin-bottom: 0px;
}
</style>
{% block course_grid %}
<div class="grid-courses row">
{% for course in courses %}
<div class="col-xs-12 col-sm-6 col-md-4">
<div class="items items-courses">
{% include 'catalog/course_item_catalog.tpl'|get_template %}
</div>
</div>
{% endfor %}
</div>
{% endblock %}
<div class="col-md-12">
{{ pagination }}
</div>
{% endblock %}

@ -0,0 +1,82 @@
{% block course_item %}
{% block course_image %}
<div class="image">
{% block course_thumbnail %}
<a href="{{ course.course_public_url }}" title="{{ course.title }}">
<img class="img-responsive" src="{{ course.thumbnail }}" alt="{{ course.title }}"/>
</a>
{% endblock %}
{% if course.category_title %}
<span class="category">{{ course.category_title }}</span>
<div class="cribbon"></div>
{% endif %}
{% block course_description_button %}
<div class="user-actions">
{{ course.description_button }}
</div>
{% endblock %}
</div>
{% endblock %}
{% block course_description %}
<div class="description">
{% block course_title %}
{{ course.title_formatted }}
{% endblock %}
{% block course_rating %}
{{ course.rating }}
{% endblock %}
{% block course_extras %}
{% if course.extra_data %}
<div class="toolbar row">
<div class="col-sm-12">
{{ course.extra_data }}
{% if course.extra_data_tags %}
<div class="panel-tags">
<ul class="list-inline course-tags">
<li> {{ 'Tags' | get_lang }}</li>
{% for tag in course.extra_data_tags %}
<li class="label label-info">
<span>{{ tag }}</span>
</li>
{% endfor %}
</ul>
</div>
{% endif %}
</div>
</div>
{% endif %}
{% endblock %}
{% block course_teacher_info %}
{{ course.teacher_info }}
{% endblock %}
{% block course_buy_course %}
{{ course.buy_course }}
{% endblock %}
{% block course_toolbar %}
<div class="toolbar row">
{% if course.already_registered_formatted %}
<div class="col-sm-6">
{{ course.unregister_formatted }}
</div>
<div class="col-sm-6">
{{ course.already_registered_formatted }}
</div>
{% else %}
<div class="col-sm-12">
{{ course.subscribe_formatted }}
</div>
{% endif %}
</div>
{% endblock %}
</div>
{% endblock %}
{% endblock %}

@ -235,6 +235,7 @@
</div>
</div>
</div>
<!-- end view session grib -->
{{ catalog_pagination }}
{% endblock %}
Loading…
Cancel
Save