Skip to content

Commit

Permalink
Admin: Add course/session report with links to tools - refs chamilo#2034
Browse files Browse the repository at this point in the history
  • Loading branch information
christianbeeznest committed Jan 18, 2025
1 parent fc4bda9 commit 3f27434
Show file tree
Hide file tree
Showing 3 changed files with 200 additions and 0 deletions.
61 changes: 61 additions & 0 deletions public/main/admin/statistics/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,7 @@
get_lang('Courses') => [
'report=courses' => get_lang('Courses'),
'report=tools' => get_lang('Tools access'),
'report=tool_usage' => get_lang('Tool Usage Report'),
'report=courselastvisit' => get_lang('Latest access'),
'report=coursebylanguage' => get_lang('Number of courses by language'),
],
Expand Down Expand Up @@ -708,6 +709,66 @@
$content .= '<canvas class="col-md-12" id="canvas" height="300px" style="margin-bottom: 20px"></canvas>';
$content .= Statistics::printToolStats();
break;
case 'tool_usage':
$courseTools = Statistics::getAvailableTools();

if (empty($courseTools)) {
$content .= '<div class="alert alert-info">'.get_lang('No tools available for this report').'</div>';
break;
}

$form = new FormValidator('tool_usage', 'get');
$form->addHeader(get_lang('Tool Usage Report'));
$form->addSelect(
'tool_ids',
get_lang('Select Tools'),
$courseTools,
['multiple' => true, 'required' => true]
);
$form->addButtonSearch(get_lang('Generate Report'));
$form->addHidden('report', 'tool_usage');

$content .= $form->returnForm();

if ($form->validate()) {
$values = $form->getSubmitValues();
$toolIds = $values['tool_ids'];
$reportData = Statistics::getToolUsageReportByTools($toolIds);

$table = new HTML_Table(['class' => 'table table-hover table-striped data_table stats_table']);
$headers = [
get_lang('Tool'),
get_lang('Session'),
get_lang('Course'),
get_lang('Items Count'),
get_lang('Last Updated'),
];
$row = 0;

foreach ($headers as $index => $header) {
$table->setHeaderContents($row, $index, $header);
}
$row++;

foreach ($reportData as $data) {
$linkHtml = $data['link'] !== '-'
? sprintf(
'<a href="%s" class="text-blue-500 underline hover:text-blue-700" target="_self">%s</a>',
$data['link'],
htmlspecialchars($data['tool_name'])
)
: htmlspecialchars($data['tool_name']);

$table->setCellContents($row, 0, $linkHtml);
$table->setCellContents($row, 1, htmlspecialchars($data['session_name']));
$table->setCellContents($row, 2, htmlspecialchars($data['course_name']));
$table->setCellContents($row, 3, (int) $data['resource_count']);
$table->setCellContents($row, 4, htmlspecialchars($data['last_updated']));
$row++;
}
$content .= $table->toHtml();
}
break;
case 'coursebylanguage':
$content .= '<canvas class="col-md-12" id="canvas" height="300px" style="margin-bottom: 20px"></canvas>';
$result = Statistics::printCourseByLanguageStats();
Expand Down
24 changes: 24 additions & 0 deletions public/main/inc/lib/statistics.lib.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

use Chamilo\CoreBundle\Component\Utils\ChamiloApi;
use Chamilo\CoreBundle\Entity\MessageRelUser;
use Chamilo\CoreBundle\Entity\ResourceLink;
use Chamilo\CoreBundle\Entity\UserRelUser;
use Chamilo\CoreBundle\Component\Utils\ActionIcon;

Expand Down Expand Up @@ -1665,4 +1666,27 @@ public static function groupByMonth(array $registrations): array

return $groupedData;
}

/**
* Retrieves the available tools using the repository.
*/
public static function getAvailableTools(): array
{
$em = Database::getManager();
$repo = $em->getRepository(ResourceLink::class);

return $repo->getAvailableTools();
}

/**
* Generates a report of tool usage based on the provided tool IDs.
*/
public static function getToolUsageReportByTools(array $toolIds): array
{
$em = Database::getManager();
$repo = $em->getRepository(ResourceLink::class);

return $repo->getToolUsageReportByTools($toolIds);
}

}
115 changes: 115 additions & 0 deletions src/CoreBundle/Repository/ResourceLinkRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,23 @@

class ResourceLinkRepository extends SortableRepository
{
private array $toolList = [
'course_description' => '/main/course_description/index.php',
'document' => '/resources/document/%resource_node_id%/',
'learnpath' => '/main/lp/lp_controller.php',
'link' => '/resources/links/%resource_node_id%/',
'quiz' => '/main/exercise/exercise.php',
'announcement' => '/main/announcements/announcements.php',
'glossary' => '/resources/glossary/%resource_node_id%/',
'attendance' => '/main/attendance/index.php',
'course_progress' => '/main/course_progress/index.php',
'agenda' => '/resources/ccalendarevent',
'forum' => '/main/forum/index.php',
'student_publication' => '/resources/assignment/%resource_node_id%',
'survey' => '/main/survey/survey_list.php',
'notebook' => '/main/notebook/index.php',
];

public function __construct(EntityManagerInterface $em)
{
parent::__construct($em, $em->getClassMetadata(ResourceLink::class));
Expand Down Expand Up @@ -50,4 +67,102 @@ public function removeByResourceInContext(
$this->remove($link);
}
}

/**
* Retrieves the list of available tools filtered by a predefined tool list.
*
* @return array The list of tools with their IDs and titles.
*/
public function getAvailableTools(): array
{
$queryBuilder = $this->_em->createQueryBuilder();
$queryBuilder
->select('DISTINCT t.id, t.title')
->from('ChamiloCoreBundle:ResourceLink', 'rl')
->innerJoin('ChamiloCoreBundle:ResourceType', 'rt', 'WITH', 'rt.id = rl.resourceTypeGroup')
->innerJoin('ChamiloCoreBundle:Tool', 't', 'WITH', 't.id = rt.tool')
->where('rl.course IS NOT NULL')
->andWhere('t.title IN (:toolList)')
->setParameter('toolList', array_keys($this->toolList));

$result = $queryBuilder->getQuery()->getArrayResult();

$tools = [];
foreach ($result as $row) {
$tools[$row['id']] = ucfirst(str_replace('_', ' ', $row['title']));
}

return $tools;
}

/**
* Retrieves a usage report of tools with dynamic links.
*
* @return array The tool usage data including counts, last update timestamps, and dynamic links.
*/
public function getToolUsageReportByTools(array $toolIds): array
{
$queryBuilder = $this->_em->createQueryBuilder();

$queryBuilder
->select(
'COUNT(rl.id) AS resource_count',
'IDENTITY(rl.course) AS course_id',
'IDENTITY(rl.session) AS session_id',
'IDENTITY(c.resourceNode) AS course_resource_node_id',
't.title AS tool_name',
'c.title AS course_name',
's.title AS session_name',
'MAX(rl.updatedAt) AS last_updated'
)
->from('ChamiloCoreBundle:ResourceLink', 'rl')
->innerJoin('ChamiloCoreBundle:ResourceType', 'rt', 'WITH', 'rt.id = rl.resourceTypeGroup')
->innerJoin('ChamiloCoreBundle:Tool', 't', 'WITH', 't.id = rt.tool')
->innerJoin('ChamiloCoreBundle:Course', 'c', 'WITH', 'c.id = rl.course')
->leftJoin('ChamiloCoreBundle:Session', 's', 'WITH', 's.id = rl.session')
->where($queryBuilder->expr()->in('t.id', ':toolIds'))
->groupBy('rl.course, rl.session, t.title')
->orderBy('t.title', 'ASC')
->addOrderBy('c.title', 'ASC')
->addOrderBy('s.title', 'ASC')
->setParameter('toolIds', $toolIds);

$result = $queryBuilder->getQuery()->getArrayResult();

return array_map(function ($row) {
$toolName = $row['tool_name'];
$baseLink = $this->toolList[$toolName] ?? null;

if ($baseLink) {
$link = str_replace(
['%resource_node_id%'],
[$row['course_resource_node_id']],
$baseLink
);

$queryParams = [
'cid' => $row['course_id'],
];

if (!empty($row['session_id'])) {
$queryParams['sid'] = $row['session_id'];
}

$link .= '?' . http_build_query($queryParams);
} else {
$link = '-';
}

return [
'tool_name' => $toolName,
'session_id' => $row['session_id'],
'session_name' => $row['session_name'] ?: '-',
'course_id' => $row['course_id'],
'course_name' => $row['course_name'],
'resource_count' => (int)$row['resource_count'],
'last_updated' => $row['last_updated'] ?: '-',
'link' => $link,
];
}, $result);
}
}

0 comments on commit 3f27434

Please sign in to comment.