course catalog sorting - refs BT#16818

pull/3183/head
Sébastien Ducoulombier 6 years ago
parent 64a867034e
commit e5dee89515
  1. 19
      main/auth/courses.php
  2. 140
      main/inc/lib/CoursesAndSessionsCatalog.class.php
  3. 5
      main/install/configuration.dist.php
  4. 119
      src/Chamilo/CoreBundle/Entity/ExtraField.php

@ -236,6 +236,13 @@ switch ($action) {
$jqueryReadyContent = $returnParams['jquery_ready_content'];
}
$sortKeySelect = $form->addSelect(
'sortKeys',
get_lang('SortKeys'),
CoursesAndSessionsCatalog::courseSortOptions(),
[ 'multiple' => true ]
);
$conditions = [];
$fields = [];
@ -314,7 +321,14 @@ switch ($action) {
$conditions = $extraField->parseConditions($options, 'course');
}
$courses = CoursesAndSessionsCatalog::searchCourses($categoryCode, $searchTerm, $limit, true, $conditions);
$courses = CoursesAndSessionsCatalog::searchAndSortCourses(
$categoryCode,
$searchTerm,
$limit,
true,
$conditions,
$sortKeySelect->getValue()
);
$countCoursesInCategory = CourseCategory::countCoursesInCategory(
$categoryCode,
$searchTerm,
@ -367,7 +381,8 @@ switch ($action) {
$pageTotal,
$categoryCode,
$action,
$fields
$fields,
$sortKeySelect->getValue()
);
}

@ -14,7 +14,7 @@ use Doctrine\ORM\Query\Expr\Join;
*/
class CoursesAndSessionsCatalog
{
const PAGE_LENGTH = 12;
const PAGE_LENGTH = 4;
/**
* Check the configuration for the courses and sessions catalog.
@ -539,6 +539,104 @@ class CoursesAndSessionsCatalog
return $courses;
}
/**
* Gets the extra fields listed in configuration option course_catalogue_order_by_extrafield
*
* @return ExtraField[]
*/
public static function getCourseExtraFieldsAvailableForSorting() {
$variables = api_get_configuration_sub_value('course_catalogue_order_by_extrafield/fields');
if (is_array($variables) && !empty($variables)) {
return ExtraField::getExtraFieldsFromVariablesOrdered($variables, ExtraField::COURSE_FIELD_TYPE);
}
return [];
}
/**
* Builds the list of possible course sort criteria to be used in an HTML select element
*
* @return array select option name => display text
*/
public static function courseSortOptions() {
/** @var $extraFields ExtraField[] */
$options = [
'title' => get_lang('Title'),
'creation_date' => get_lang('CreationDate'),
'count_users' => get_lang('SubscriptionCount'),
'point_info/users' => get_lang('VoteCount'),
];
foreach (self::getCourseExtraFieldsAvailableForSorting() as $extraField) {
$options['extra_field_' . $extraField->getId()] = $extraField->getDisplayText();
}
return $options;
}
/**
* Wrapper for self::searchCourses which locally sorts the results according to $sortKey
*
* @param string $categoryCode can be 'ALL', 'NONE' or any existing course category code
* @param string $keyword search pattern to be found in course code, title or tutor_name
* @param array $limit associative array generated by \CoursesAndSessionsCatalog::getLimitArray()
* @param bool $justVisible search only on visible courses in the catalogue
* @param array $conditions associative array generated using \ExtraField::parseConditions
* @param string[] $sortKeys a subset of the keys of the array returned by courseSortOptions()
*
* @return array list of all the courses matching the the search term
*/
public static function searchAndSortCourses(
$categoryCode,
$keyword,
$limit,
$justVisible = false,
$conditions = [],
$sortKeys = []
) {
// Get ALL matching courses (no limit)
$courses = self::searchCourses($categoryCode, $keyword, null, $justVisible, $conditions);
// Do we have extra fields to sort on ?
$extraFieldsToSortOn = [];
foreach (self::getCourseExtraFieldsAvailableForSorting() as $extraField) {
if (in_array('extra_field_' . $extraField->getId(), $sortKeys)) {
$extraFieldsToSortOn[] = $extraField;
}
}
if (!empty($extraFieldsToSortOn)) {
// load extra field values and store them in $courses
$courseIds = [];
foreach ($courses as $course) {
$courseIds[] = $course['real_id'];
}
$values = ExtraField::getValueForEachExtraFieldForEachItem($extraFieldsToSortOn, $courseIds);
foreach ($courses as &$course) {
$courseId = $course['real_id'];
if (array_key_exists($courseId, $values)) {
foreach ($values[$courseId] as $extraFieldId => $value) {
$course['extra_field_' . $extraFieldId] = $value;
}
}
}
}
// do we have special cases to sort on ?
if (in_array('point_info/users', $sortKeys)) {
foreach ($courses as &$course) {
if (array_key_exists('point_info', $course) && array_key_exists('users', $course['point_info'])) {
$course['point_info/users'] = $course['point_info']['users'];
}
}
}
usort($courses, function ($a, $b) use ($sortKeys) {
foreach ($sortKeys as $key) {
$valueA = array_key_exists($key, $a) ? $a[$key] : null;
$valueB = array_key_exists($key, $b) ? $b[$key] : null;
if ($valueA !== $valueB) {
return $valueA < $valueB ? -1 : 1;
}
}
return 0;
});
return array_slice($courses, $limit['start'], $limit['length']);
}
/**
* List the sessions.
*
@ -1511,6 +1609,7 @@ class CoursesAndSessionsCatalog
* @param string $categoryCode
* @param string $action
* @param array $fields
* @param array $sortKeys
*
* @return string
*/
@ -1520,7 +1619,8 @@ class CoursesAndSessionsCatalog
$pageTotal,
$categoryCode = '',
$action = '',
$fields = []
$fields = [],
$sortKeys
) {
// Start empty html
$pageDiv = '';
@ -1538,7 +1638,8 @@ class CoursesAndSessionsCatalog
'...',
$categoryCode,
$action,
$fields
$fields,
$sortKeys
);
}
}
@ -1557,7 +1658,8 @@ class CoursesAndSessionsCatalog
'',
$categoryCode,
$action,
$fields
$fields,
$sortKeys
);
}
@ -1571,10 +1673,20 @@ class CoursesAndSessionsCatalog
'...',
$categoryCode,
$action,
$fields
$fields,
$sortKeys
);
}
$pageDiv .= self::getPageNumberItem($pageTotal, $pageLength, [], '', $categoryCode, $action, $fields);
$pageDiv .= self::getPageNumberItem(
$pageTotal,
$pageLength,
[],
'',
$categoryCode,
$action,
$fields,
$sortKeys
);
}
// Complete pagination html
@ -1594,6 +1706,7 @@ class CoursesAndSessionsCatalog
* @param string $categoryCode
* @param string $action
* @param array $fields
* @param array $sortKeys
*
* @return string
*/
@ -1604,10 +1717,11 @@ class CoursesAndSessionsCatalog
$content = '',
$categoryCode = '',
$action = '',
$fields = []
$fields = [],
$sortKeys = []
) {
// Get page URL
$url = self::getCatalogUrl($pageNumber, $pageLength, $categoryCode, $action, $fields);
$url = self::getCatalogUrl($pageNumber, $pageLength, $categoryCode, $action, $fields, $sortKeys);
// If is current page ('active' class) clear URL
if (isset($liAttributes) && is_array($liAttributes) && isset($liAttributes['class'])) {
@ -1636,6 +1750,7 @@ class CoursesAndSessionsCatalog
* @param string $categoryCode
* @param string $action
* @param array $extraFields
* @param array $sortKeys
*
* @return string
*/
@ -1644,7 +1759,8 @@ class CoursesAndSessionsCatalog
$pageLength,
$categoryCode = null,
$action = null,
$extraFields = []
$extraFields = [],
$sortKeys = []
) {
$requestAction = isset($_REQUEST['action']) ? Security::remove_XSS($_REQUEST['action']) : null;
$action = isset($action) ? Security::remove_XSS($action) : $requestAction;
@ -1673,6 +1789,12 @@ class CoursesAndSessionsCatalog
}
}
if (!empty($sortKeys)) {
foreach ($sortKeys as $sortKey) {
$pageUrl .= '&sortKeys%5B%5D=' . Security::remove_XSS($sortKey);
}
}
switch ($action) {
case 'subscribe':
// for search

@ -1453,6 +1453,11 @@ $_configuration['course_catalog_settings'] = [
// Disable sending emails.
//$_configuration['disable_send_mail'] = false;
// Page "Catalog" extra fields to be used as sorting criteria
/*$_configuration['course_catalogue_order_by_extrafield'] = [
'fields' => ['duree_en_min'],
];*/
// KEEP THIS AT THE END
// -------- Custom DB changes
// Add user activation by confirmation email

@ -3,6 +3,8 @@
namespace Chamilo\CoreBundle\Entity;
use Database;
use Doctrine\Common\Collections\Criteria;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Sylius\Component\Attribute\Model\Attribute as BaseAttribute;
@ -369,4 +371,121 @@ class ExtraField extends BaseAttribute
return 'text';
}
}
/**
* Retreives and returns the value stored in this extra field for an item
*
* @param $itemId string|int the item identifier
*
* @return mixed|null the value if found, null if not found
*/
public function getValueForItem($itemId)
{
$values = Database::getManager()->getRepository(
"ChamiloCoreBundle:ExtraFieldValues"
)->matching(
Criteria::create()->where(
Criteria::expr()->eq('field', $this)
)->andWhere(
Criteria::expr()->eq('itemId', $itemId)
)
);
return count($values) === 1 ? $values[0] : null;
}
/**
* Retreives and returns the value stored in this extra field for each item
*
* @return array itemId => value
*/
public function getValueForEachItem()
{
$values = [];
/** @var ExtraFieldValues $value */
foreach (Database::getManager()->getRepository(
"ChamiloCoreBundle:ExtraFieldValues"
)->matching(
Criteria::create()->where(
Criteria::expr()->eq('field', $this)
)
) as $value) {
$values[$value->getItemId()] = $value->getValue();
}
return $values;
}
/**
* Retreives and returns the value stored in each extra field for each item
*
* @param ExtraField[] $extraFields
*
* @return array itemId => [ fieldId => value ]
*/
public static function getValueForEachExtraFieldForEachItem($extraFields, $itemIds)
{
$values = [];
/** @var ExtraFieldValues $value */
foreach (Database::getManager()->getRepository(
"ChamiloCoreBundle:ExtraFieldValues"
)->matching(
Criteria::create()->where(
Criteria::expr()->in('field', $extraFields)
)->andWhere(
Criteria::expr()->in('itemId', $itemIds)
)
) as $value) {
$itemId = $value->getItemId();
if (!array_key_exists($itemId, $values)) {
$values[$itemId] = [];
}
$values[$itemId][$value->getField()->getId()] = $value->getValue();
}
return $values;
}
/**
* Retreives extra fields from a list of variables
*
* @param string[] $variables extra field variables
* @param int $extraFieldType such as self::COURSE_FIELD_TYPE
*
* @return ExtraField[] found extra fields
*/
public static function getExtraFieldsFromVariables($variables, $extraFieldType)
{
/** @var ExtraField[] $extraFields */
$extraFields = Database::getManager()->getRepository("ChamiloCoreBundle:ExtraField")->matching(
Criteria::create()->where(
Criteria::expr()->eq('extraFieldType', $extraFieldType)
)->andWhere(
Criteria::expr()->in('variable', $variables)
)
);
return $extraFields;
}
/**
* Retreives and sorts extra fields from a list of variables
*
* @param string[] $variables extra field variables
* @param int $extraFieldType such as self::COURSE_FIELD_TYPE
*
* @return ExtraField[] the sorted extra fields, in the same order as the variables
*/
public static function getExtraFieldsFromVariablesOrdered($variables, $extraFieldType)
{
/** @var ExtraField[] $sortedExtraFields */
$sortedExtraFields = [];
/** @var ExtraField[] $extraFields */
$extraFields = self::getExtraFieldsFromVariables($variables, $extraFieldType);
foreach ($variables as $variable) {
foreach ($extraFields as $extraField) {
if ($extraField->getVariable() === $variable) {
$sortedExtraFields[] = $extraField;
break;
}
}
}
return $sortedExtraFields;
}
}

Loading…
Cancel
Save