upgrade
This commit is contained in:
1
main/inc/ajax/.htaccess
Normal file
1
main/inc/ajax/.htaccess
Normal file
@@ -0,0 +1 @@
|
||||
Options -Indexes
|
||||
BIN
main/inc/ajax/Wami.swf
Normal file
BIN
main/inc/ajax/Wami.swf
Normal file
Binary file not shown.
272
main/inc/ajax/admin.ajax.php
Normal file
272
main/inc/ajax/admin.ajax.php
Normal file
@@ -0,0 +1,272 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use Chamilo\CoreBundle\Entity\BranchSync;
|
||||
use Chamilo\CoreBundle\Entity\Repository\BranchSyncRepository;
|
||||
use GuzzleHttp\Client;
|
||||
|
||||
/**
|
||||
* Responses to AJAX calls.
|
||||
*/
|
||||
require_once __DIR__.'/../global.inc.php';
|
||||
|
||||
api_protect_admin_script();
|
||||
|
||||
$action = isset($_REQUEST['a']) ? $_REQUEST['a'] : null;
|
||||
|
||||
switch ($action) {
|
||||
case 'update_changeable_setting':
|
||||
$url_id = api_get_current_access_url_id();
|
||||
|
||||
if (api_is_global_platform_admin() && $url_id == 1) {
|
||||
if (isset($_GET['id']) && !empty($_GET['id'])) {
|
||||
$params = ['variable = ? ' => [$_GET['id']]];
|
||||
$data = api_get_settings_params($params);
|
||||
if (!empty($data)) {
|
||||
foreach ($data as $item) {
|
||||
$params = ['id' => $item['id'], 'access_url_changeable' => $_GET['changeable']];
|
||||
api_set_setting_simple($params);
|
||||
}
|
||||
}
|
||||
echo '1';
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'version':
|
||||
// Fix session block when loading admin/index.php and changing page
|
||||
session_write_close();
|
||||
echo version_check();
|
||||
break;
|
||||
case 'get_extra_content':
|
||||
$blockName = isset($_POST['block']) ? Security::remove_XSS($_POST['block']) : null;
|
||||
|
||||
if (empty($blockName)) {
|
||||
exit;
|
||||
}
|
||||
|
||||
if (api_is_multiple_url_enabled()) {
|
||||
$accessUrlId = api_get_current_access_url_id();
|
||||
|
||||
if ($accessUrlId == -1) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$urlInfo = api_get_access_url($accessUrlId);
|
||||
$url = api_remove_trailing_slash(preg_replace('/https?:\/\//i', '', $urlInfo['url']));
|
||||
$cleanUrl = str_replace('/', '-', $url);
|
||||
$newUrlDir = api_get_path(SYS_APP_PATH)."home/$cleanUrl/admin/";
|
||||
} else {
|
||||
$newUrlDir = api_get_path(SYS_APP_PATH)."home/admin/";
|
||||
}
|
||||
|
||||
if (!file_exists($newUrlDir)) {
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!Security::check_abs_path("{$newUrlDir}{$blockName}_extra.html", $newUrlDir)) {
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!file_exists("{$newUrlDir}{$blockName}_extra.html")) {
|
||||
exit;
|
||||
}
|
||||
|
||||
echo file_get_contents("{$newUrlDir}{$blockName}_extra.html");
|
||||
break;
|
||||
case 'get_latest_news':
|
||||
if (api_get_configuration_value('admin_chamilo_announcements_disable') === true) {
|
||||
break;
|
||||
}
|
||||
|
||||
try {
|
||||
$latestNews = getLatestNews();
|
||||
$latestNews = json_decode($latestNews, true);
|
||||
|
||||
echo Security::remove_XSS($latestNews['text'], COURSEMANAGER);
|
||||
break;
|
||||
} catch (Exception $e) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays either the text for the registration or the message that the installation is (not) up to date.
|
||||
*
|
||||
* @return string html code
|
||||
*
|
||||
* @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
|
||||
*
|
||||
* @version august 2006
|
||||
*
|
||||
* @todo have a 6 monthly re-registration
|
||||
*/
|
||||
function version_check()
|
||||
{
|
||||
$tbl_settings = Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
|
||||
$sql = 'SELECT selected_value FROM '.$tbl_settings.' WHERE variable = "registered" ';
|
||||
$result = Database::query($sql);
|
||||
$row = Database::fetch_array($result, 'ASSOC');
|
||||
|
||||
// The site has not been registered yet.
|
||||
$return = '';
|
||||
if ($row['selected_value'] == 'false') {
|
||||
$return .= get_lang('VersionCheckExplanation');
|
||||
$return .= '<form class="version-checking" action="'.api_get_path(WEB_CODE_PATH).'admin/index.php" id="VersionCheck" name="VersionCheck" method="post">';
|
||||
$return .= '<label class="checkbox"><input type="checkbox" name="donotlistcampus" value="1" id="checkbox" />'.get_lang('HideCampusFromPublicPlatformsList');
|
||||
$return .= '</label><button type="submit" class="btn btn-primary btn-block" name="Register" value="'.get_lang('EnableVersionCheck').'" id="register" >'.get_lang('EnableVersionCheck').'</button>';
|
||||
$return .= '</form>';
|
||||
check_system_version();
|
||||
} else {
|
||||
// site not registered. Call anyway
|
||||
$return .= check_system_version();
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current installation is up to date
|
||||
* The code is borrowed from phpBB and slighlty modified.
|
||||
*
|
||||
* @throws \Exception
|
||||
* @throws \InvalidArgumentException
|
||||
*
|
||||
* @return string language string with some layout (color)
|
||||
*/
|
||||
function check_system_version()
|
||||
{
|
||||
// Check if curl is available.
|
||||
if (!in_array('curl', get_loaded_extensions())) {
|
||||
return '<span style="color:red">'.get_lang('ImpossibleToContactVersionServerPleaseTryAgain').'</span>';
|
||||
}
|
||||
|
||||
$url = 'https://version.chamilo.org';
|
||||
$options = [
|
||||
'verify' => false,
|
||||
];
|
||||
|
||||
$urlValidated = false;
|
||||
|
||||
try {
|
||||
$client = new GuzzleHttp\Client();
|
||||
$res = $client->request('GET', $url, $options);
|
||||
if ($res->getStatusCode() == '200' || $res->getStatusCode() == '301') {
|
||||
$urlValidated = true;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
|
||||
// the chamilo version of your installation
|
||||
$system_version = trim(api_get_configuration_value('system_version'));
|
||||
|
||||
if ($urlValidated) {
|
||||
// The number of courses
|
||||
$number_of_courses = Statistics::countCourses();
|
||||
|
||||
// The number of users
|
||||
$number_of_users = Statistics::countUsers();
|
||||
$number_of_active_users = Statistics::countUsers(
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
true
|
||||
);
|
||||
|
||||
// The number of sessions
|
||||
$number_of_sessions = SessionManager::count_sessions(api_get_current_access_url_id());
|
||||
$packager = api_get_configuration_value('packager');
|
||||
if (empty($packager)) {
|
||||
$packager = 'chamilo';
|
||||
}
|
||||
|
||||
$uniqueId = '';
|
||||
$entityManager = Database::getManager();
|
||||
/** @var BranchSyncRepository $branch */
|
||||
$repository = $entityManager->getRepository('ChamiloCoreBundle:BranchSync');
|
||||
/** @var BranchSync $branch */
|
||||
$branch = $repository->getTopBranch();
|
||||
if (is_a($branch, '\Chamilo\CoreBundle\Entity\BranchSync')) {
|
||||
$uniqueId = $branch->getUniqueId();
|
||||
}
|
||||
|
||||
$data = [
|
||||
'url' => api_get_path(WEB_PATH),
|
||||
'campus' => api_get_setting('siteName'),
|
||||
'contact' => api_get_setting('emailAdministrator'), // the admin's e-mail, with the only purpose of being able to contact admins to inform about critical security issues
|
||||
'version' => $system_version,
|
||||
'numberofcourses' => $number_of_courses, // to sum up into non-personal statistics - see https://version.chamilo.org/stats/
|
||||
'numberofusers' => $number_of_users, // to sum up into non-personal statistics
|
||||
'numberofactiveusers' => $number_of_active_users, // to sum up into non-personal statistics
|
||||
'numberofsessions' => $number_of_sessions,
|
||||
//The donotlistcampus setting recovery should be improved to make
|
||||
// it true by default - this does not affect numbers counting
|
||||
'donotlistcampus' => api_get_setting('donotlistcampus'),
|
||||
'organisation' => api_get_setting('Institution'),
|
||||
'language' => api_get_setting('platformLanguage'), //helps us know the spread of language usage for campuses, by main language
|
||||
'adminname' => api_get_setting('administratorName').' '.api_get_setting('administratorSurname'), //not sure this is necessary...
|
||||
'ip' => $_SERVER['REMOTE_ADDR'], //the admin's IP address, with the only purpose of trying to geolocate portals around the globe to draw a map
|
||||
// Reference to the packager system or provider through which
|
||||
// Chamilo is installed/downloaded. Packagers can change this in
|
||||
// the default config file (main/install/configuration.dist.php)
|
||||
// or in the installed config file. The default value is 'chamilo'
|
||||
'packager' => $packager,
|
||||
'unique_id' => $uniqueId,
|
||||
];
|
||||
|
||||
$version = null;
|
||||
$client = new GuzzleHttp\Client();
|
||||
$url .= '?';
|
||||
foreach ($data as $k => $v) {
|
||||
$url .= urlencode($k).'='.urlencode($v).'&';
|
||||
}
|
||||
$res = $client->request('GET', $url, $options);
|
||||
if ($res->getStatusCode() == '200') {
|
||||
$versionData = $res->getHeader('X-Chamilo-Version');
|
||||
if (isset($versionData[0])) {
|
||||
$version = trim($versionData[0]);
|
||||
}
|
||||
}
|
||||
|
||||
if (version_compare($system_version, $version, '<')) {
|
||||
$output = '<span style="color:red">'.get_lang('YourVersionNotUpToDate').'<br />
|
||||
'.get_lang('LatestVersionIs').' <b>Chamilo '.$version.'</b>. <br />
|
||||
'.get_lang('YourVersionIs').' <b>Chamilo '.$system_version.'</b>. <br />'.str_replace('http://www.chamilo.org', '<a href="http://www.chamilo.org">http://www.chamilo.org</a>', get_lang('PleaseVisitOurWebsite')).'</span>';
|
||||
} else {
|
||||
$output = '<span style="color:green">'.get_lang('VersionUpToDate').': Chamilo '.$version.'</span>';
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
return '<span style="color:red">'.get_lang('ImpossibleToContactVersionServerPleaseTryAgain').'</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the latest news from the Chamilo Association for admins.
|
||||
*
|
||||
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||
* @throws Exception
|
||||
*
|
||||
* @return string|void
|
||||
*/
|
||||
function getLatestNews()
|
||||
{
|
||||
$url = 'https://version.chamilo.org/news/latest.php';
|
||||
|
||||
$client = new Client();
|
||||
$response = $client->request(
|
||||
'GET',
|
||||
$url,
|
||||
[
|
||||
'query' => [
|
||||
'language' => api_get_interface_language(),
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
if ($response->getStatusCode() !== 200) {
|
||||
throw new Exception(get_lang('DenyEntry'));
|
||||
}
|
||||
|
||||
return $response->getBody()->getContents();
|
||||
}
|
||||
262
main/inc/ajax/agenda.ajax.php
Normal file
262
main/inc/ajax/agenda.ajax.php
Normal file
@@ -0,0 +1,262 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Responses to AJAX calls.
|
||||
*/
|
||||
$type = isset($_REQUEST['type']) && in_array($_REQUEST['type'], ['personal', 'course', 'admin']) ? $_REQUEST['type'] : 'personal';
|
||||
|
||||
if ($type === 'personal') {
|
||||
$cidReset = true; // fixes #5162
|
||||
}
|
||||
|
||||
require_once __DIR__.'/../global.inc.php';
|
||||
|
||||
$action = $_REQUEST['a'] ?? null;
|
||||
$group_id = api_get_group_id();
|
||||
|
||||
if ($type === 'course') {
|
||||
api_protect_course_script(true);
|
||||
}
|
||||
|
||||
$logInfo = [
|
||||
'tool' => TOOL_CALENDAR_EVENT,
|
||||
'action' => $action,
|
||||
];
|
||||
Event::registerLog($logInfo);
|
||||
|
||||
$agenda = new Agenda($type);
|
||||
// get filtered type
|
||||
$type = $agenda->getType();
|
||||
|
||||
$em = Database::getManager();
|
||||
|
||||
switch ($action) {
|
||||
case 'add_event':
|
||||
if (!$agenda->getIsAllowedToEdit()) {
|
||||
break;
|
||||
}
|
||||
if (false === Security::check_token('get')) {
|
||||
exit;
|
||||
}
|
||||
$add_as_announcement = $_REQUEST['add_as_annonuncement'] ?? null;
|
||||
$title = $_REQUEST['title'] ?? null;
|
||||
$content = $_REQUEST['content'] ?? null;
|
||||
$comment = $_REQUEST['comment'] ?? null;
|
||||
$userToSend = $_REQUEST['users_to_send'] ?? [];
|
||||
$inviteesList = $_REQUEST['invitees'] ?? [];
|
||||
$isCollective = isset($_REQUEST['collective']);
|
||||
$notificationCount = $_REQUEST['notification_count'] ?? [];
|
||||
$notificationPeriod = $_REQUEST['notification_period'] ?? [];
|
||||
$careerId = $_REQUEST['career_id'] ?? 0;
|
||||
$promotionId = $_REQUEST['promotion_id'] ?? 0;
|
||||
$subscriptionVisibility = (int) ($_REQUEST['subscription_visibility'] ?? 0);
|
||||
$subscriptionItemId = isset($_REQUEST['subscription_item']) ? (int) $_REQUEST['subscription_item'] : null;
|
||||
$maxSubscriptions = (int) ($_REQUEST['max_subscriptions'] ?? 0);
|
||||
|
||||
$reminders = $notificationCount ? array_map(null, $notificationCount, $notificationPeriod) : [];
|
||||
|
||||
$eventId = $agenda->addEvent(
|
||||
$_REQUEST['start'],
|
||||
$_REQUEST['end'],
|
||||
$_REQUEST['all_day'],
|
||||
$title,
|
||||
$content,
|
||||
$userToSend,
|
||||
$add_as_announcement,
|
||||
null,
|
||||
[],
|
||||
null,
|
||||
$comment,
|
||||
'',
|
||||
$inviteesList,
|
||||
$isCollective,
|
||||
$reminders,
|
||||
(int) $careerId,
|
||||
(int) $promotionId,
|
||||
$subscriptionVisibility,
|
||||
$subscriptionItemId,
|
||||
$maxSubscriptions
|
||||
);
|
||||
|
||||
echo $eventId;
|
||||
break;
|
||||
case 'edit_event':
|
||||
if (!$agenda->getIsAllowedToEdit()) {
|
||||
break;
|
||||
}
|
||||
if (false === Security::check_token('get')) {
|
||||
exit;
|
||||
}
|
||||
$id_list = explode('_', $_REQUEST['id']);
|
||||
$id = $id_list[1];
|
||||
$agenda->editEvent(
|
||||
$id,
|
||||
$_REQUEST['start'],
|
||||
$_REQUEST['end'],
|
||||
$_REQUEST['all_day'],
|
||||
$title,
|
||||
$content
|
||||
);
|
||||
break;
|
||||
case 'delete_event':
|
||||
if (!$agenda->getIsAllowedToEdit()) {
|
||||
break;
|
||||
}
|
||||
if (false === Security::check_token('get')) {
|
||||
exit;
|
||||
}
|
||||
$id_list = explode('_', $_REQUEST['id']);
|
||||
$id = $id_list[1];
|
||||
$deleteAllEventsFromSerie = isset($_REQUEST['delete_all_events']);
|
||||
$agenda->deleteEvent($id, $deleteAllEventsFromSerie);
|
||||
break;
|
||||
case 'resize_event':
|
||||
if (!$agenda->getIsAllowedToEdit()) {
|
||||
break;
|
||||
}
|
||||
if (false === Security::check_token('get')) {
|
||||
exit;
|
||||
}
|
||||
$minute_delta = $_REQUEST['minute_delta'];
|
||||
$id = explode('_', $_REQUEST['id']);
|
||||
$id = $id[1];
|
||||
$agenda->resizeEvent($id, $minute_delta);
|
||||
break;
|
||||
case 'move_event':
|
||||
if (!$agenda->getIsAllowedToEdit()) {
|
||||
break;
|
||||
}
|
||||
if (false === Security::check_token('get')) {
|
||||
exit;
|
||||
}
|
||||
$minute_delta = $_REQUEST['minute_delta'];
|
||||
$allDay = $_REQUEST['all_day'];
|
||||
$id = explode('_', $_REQUEST['id']);
|
||||
$id = $id[1];
|
||||
$agenda->move_event($id, $minute_delta, $allDay);
|
||||
break;
|
||||
case 'get_events':
|
||||
$filter = $_REQUEST['user_id'] ?? null;
|
||||
$sessionId = $_REQUEST['session_id'] ?? null;
|
||||
$result = $agenda->parseAgendaFilter($filter);
|
||||
|
||||
$groupId = current($result['groups']);
|
||||
$userId = current($result['users']);
|
||||
|
||||
$start = isset($_REQUEST['start']) ? api_strtotime($_REQUEST['start']) : null;
|
||||
$end = isset($_REQUEST['end']) ? api_strtotime($_REQUEST['end']) : null;
|
||||
|
||||
if ($type === 'personal' && !empty($sessionId)) {
|
||||
$agenda->setSessionId($sessionId);
|
||||
}
|
||||
|
||||
$events = $agenda->getEvents(
|
||||
$start,
|
||||
$end,
|
||||
api_get_course_int_id(),
|
||||
$groupId,
|
||||
$userId
|
||||
);
|
||||
header('Content-Type: application/json');
|
||||
echo $events;
|
||||
break;
|
||||
case 'get_user_agenda':
|
||||
// Used in the admin user list.
|
||||
api_protect_admin_script();
|
||||
|
||||
if (api_is_allowed_to_edit(null, true)) {
|
||||
//@todo move this in the agenda class
|
||||
$DaysShort = api_get_week_days_short();
|
||||
$MonthsLong = api_get_months_long();
|
||||
|
||||
$user_id = (int) $_REQUEST['user_id'];
|
||||
$my_course_list = CourseManager::get_courses_list_by_user_id($user_id, true);
|
||||
if (!is_array($my_course_list)) {
|
||||
// this is for the special case if the user has no courses (otherwise you get an error)
|
||||
$my_course_list = [];
|
||||
}
|
||||
$today = getdate();
|
||||
$year = (!empty($_GET['year']) ? (int) $_GET['year'] : null);
|
||||
if ($year == null) {
|
||||
$year = $today['year'];
|
||||
}
|
||||
$month = (!empty($_GET['month']) ? (int) $_GET['month'] : null);
|
||||
if ($month == null) {
|
||||
$month = $today['mon'];
|
||||
}
|
||||
$day = (!empty($_GET['day']) ? (int) $_GET['day'] : null);
|
||||
if ($day == null) {
|
||||
$day = $today['mday'];
|
||||
}
|
||||
$monthName = $MonthsLong[$month - 1];
|
||||
$week = null;
|
||||
|
||||
$agendaitems = Agenda::get_myagendaitems(
|
||||
$user_id,
|
||||
$my_course_list,
|
||||
$month,
|
||||
$year
|
||||
);
|
||||
$agendaitems = Agenda::get_global_agenda_items(
|
||||
$agendaitems,
|
||||
$day,
|
||||
$month,
|
||||
$year,
|
||||
$week,
|
||||
"month_view"
|
||||
);
|
||||
|
||||
if (api_get_setting('allow_personal_agenda') == 'true') {
|
||||
$agendaitems = Agenda::get_personal_agenda_items(
|
||||
$user_id,
|
||||
$agendaitems,
|
||||
$day,
|
||||
$month,
|
||||
$year,
|
||||
$week,
|
||||
"month_view"
|
||||
);
|
||||
}
|
||||
Agenda::display_mymonthcalendar(
|
||||
$user_id,
|
||||
$agendaitems,
|
||||
$month,
|
||||
$year,
|
||||
[],
|
||||
$monthName,
|
||||
false
|
||||
);
|
||||
}
|
||||
break;
|
||||
case 'event_subscribe':
|
||||
if (!$agenda->getIsAllowedToEdit()) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (false === Security::check_token('get')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$id = (int) explode('_', $_REQUEST['id'])[1];
|
||||
|
||||
$agenda->subscribeCurrentUserToEvent($id);
|
||||
break;
|
||||
case 'event_unsubscribe':
|
||||
if (!$agenda->getIsAllowedToEdit()) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (false === Security::check_token('get')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$id = (int) explode('_', $_REQUEST['id'])[1];
|
||||
|
||||
$agenda->unsubscribeCurrentUserToEvent($id);
|
||||
break;
|
||||
default:
|
||||
echo '';
|
||||
}
|
||||
exit;
|
||||
233
main/inc/ajax/announcement.ajax.php
Normal file
233
main/inc/ajax/announcement.ajax.php
Normal file
@@ -0,0 +1,233 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Responses to AJAX calls.
|
||||
*/
|
||||
require_once __DIR__.'/../global.inc.php';
|
||||
|
||||
$action = $_REQUEST['a'] ?? null;
|
||||
|
||||
$isAllowedToEdit = api_is_allowed_to_edit();
|
||||
$courseInfo = api_get_course_info();
|
||||
$courseCode = api_get_course_id();
|
||||
$courseId = api_get_course_int_id();
|
||||
$groupId = api_get_group_id();
|
||||
$sessionId = api_get_session_id();
|
||||
$currentUserId = api_get_user_id();
|
||||
|
||||
$isTutor = false;
|
||||
if (!empty($groupId)) {
|
||||
$groupInfo = GroupManager::get_group_properties($groupId);
|
||||
$isTutor = GroupManager::is_tutor_of_group(api_get_user_id(), $groupInfo);
|
||||
if ($isTutor) {
|
||||
$isAllowedToEdit = true;
|
||||
}
|
||||
}
|
||||
|
||||
switch ($action) {
|
||||
case 'preview':
|
||||
$userInCourse = false;
|
||||
if ($courseId != 0 && CourseManager::is_user_subscribed_in_course($currentUserId, CourseManager::get_course_code_from_course_id($courseId), $sessionId)) {
|
||||
$userInCourse = true;
|
||||
}
|
||||
$allowToEdit = (
|
||||
api_is_allowed_to_edit(false, true) ||
|
||||
(api_get_course_setting('allow_user_edit_announcement') && !api_is_anonymous() && $userInCourse) ||
|
||||
($sessionId && api_is_coach() && api_get_configuration_value('allow_coach_to_edit_announcements'))
|
||||
);
|
||||
|
||||
$drhHasAccessToSessionContent = api_drh_can_access_all_session_content();
|
||||
if (!empty($sessionId) && $drhHasAccessToSessionContent) {
|
||||
$allowToEdit = $allowToEdit || api_is_drh();
|
||||
}
|
||||
|
||||
if ($allowToEdit === false && !empty($groupId)) {
|
||||
$groupProperties = GroupManager::get_group_properties($groupId);
|
||||
// Check if user is tutor group
|
||||
$isTutor = GroupManager::is_tutor_of_group(api_get_user_id(), $groupProperties, $courseId);
|
||||
if ($isTutor) {
|
||||
$allowToEdit = true;
|
||||
}
|
||||
|
||||
// Last chance ... students can send announcements.
|
||||
if ($groupProperties['announcements_state'] == GroupManager::TOOL_PRIVATE_BETWEEN_USERS) {
|
||||
// check if user is a group member to give access
|
||||
$groupInfo = GroupManager::get_group_properties($groupId);
|
||||
if (array_key_exists($currentUserId, GroupManager::get_subscribed_users($groupInfo))) {
|
||||
$allowToEdit = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($allowToEdit === false) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$users = isset($_REQUEST['users']) ? json_decode($_REQUEST['users']) : '';
|
||||
$formParams = [];
|
||||
if (isset($_REQUEST['form'])) {
|
||||
parse_str($_REQUEST['form'], $formParams);
|
||||
}
|
||||
|
||||
$previewGroups = [];
|
||||
$previewUsers = [];
|
||||
$previewTotal = [];
|
||||
if (empty($groupId)) {
|
||||
if (empty($users) ||
|
||||
(!empty($users) && isset($users[0]) && $users[0] == 'everyone')
|
||||
) {
|
||||
// All users in course session
|
||||
if (empty($sessionId)) {
|
||||
$students = CourseManager::get_user_list_from_course_code($courseInfo['code']);
|
||||
} else {
|
||||
$students = CourseManager::get_user_list_from_course_code($courseInfo['code'], $sessionId);
|
||||
}
|
||||
foreach ($students as $student) {
|
||||
$previewUsers[] = $student['user_id'];
|
||||
}
|
||||
|
||||
$groupList = GroupManager::get_group_list(null, $courseInfo, null, $sessionId);
|
||||
foreach ($groupList as $group) {
|
||||
$previewGroups[] = $group['iid'];
|
||||
}
|
||||
} else {
|
||||
$send_to = CourseManager::separateUsersGroups($users);
|
||||
// Storing the selected groups
|
||||
if (is_array($send_to['groups']) &&
|
||||
!empty($send_to['groups'])
|
||||
) {
|
||||
$counter = 1;
|
||||
foreach ($send_to['groups'] as $group) {
|
||||
$previewGroups[] = $group;
|
||||
}
|
||||
}
|
||||
|
||||
// Storing the selected users
|
||||
if (is_array($send_to['users'])) {
|
||||
$counter = 1;
|
||||
foreach ($send_to['users'] as $user) {
|
||||
$previewUsers[] = $user;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$send_to_users = CourseManager::separateUsersGroups($users);
|
||||
$sentToAllGroup = false;
|
||||
if (empty($send_to_users['groups']) && empty($send_to_users['users'])) {
|
||||
$previewGroups[] = $groupId;
|
||||
$sentToAllGroup = true;
|
||||
}
|
||||
|
||||
if ($sentToAllGroup === false) {
|
||||
if (!empty($send_to_users['groups'])) {
|
||||
foreach ($send_to_users['groups'] as $group) {
|
||||
$previewGroups[] = $group;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($send_to_users['users'])) {
|
||||
foreach ($send_to_users['users'] as $user) {
|
||||
$previewUsers[] = $user;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($formParams['send_to_users_in_session']) && $formParams['send_to_users_in_session'] == 1) {
|
||||
$sessionList = SessionManager::get_session_by_course(api_get_course_int_id());
|
||||
|
||||
if (!empty($sessionList)) {
|
||||
foreach ($sessionList as $sessionInfo) {
|
||||
$sessionId = $sessionInfo['id'];
|
||||
$userList = CourseManager::get_user_list_from_course_code(
|
||||
$courseCode,
|
||||
$sessionId
|
||||
);
|
||||
|
||||
if (!empty($userList)) {
|
||||
foreach ($userList as $user) {
|
||||
$previewUsers[] = $user;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($formParams['send_to_hrm_users']) && $formParams['send_to_hrm_users'] == 1) {
|
||||
foreach ($previewUsers as $userId) {
|
||||
$userInfo = api_get_user_info($userId);
|
||||
$drhList = UserManager::getDrhListFromUser($userId);
|
||||
if (!empty($drhList)) {
|
||||
foreach ($drhList as $drhInfo) {
|
||||
$previewUsers[] = $drhInfo['id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($formParams['send_me_a_copy_by_email']) && $formParams['send_me_a_copy_by_email'] == 1) {
|
||||
$previewUsers[] = api_get_user_id();
|
||||
}
|
||||
|
||||
$previewUserNames = [];
|
||||
$previewGroupNames = [];
|
||||
|
||||
if (!empty($previewGroups)) {
|
||||
$previewGroups = array_unique($previewGroups);
|
||||
foreach ($previewGroups as $groupId) {
|
||||
$groupInfo = GroupManager::get_group_properties($groupId);
|
||||
$previewGroupNames[] = Display::label($groupInfo['name'], 'info');
|
||||
}
|
||||
$previewTotal = $previewGroupNames;
|
||||
}
|
||||
|
||||
if (!empty($previewUsers)) {
|
||||
$previewUsers = array_unique($previewUsers);
|
||||
foreach ($previewUsers as $userId) {
|
||||
$userInfo = api_get_user_info($userId);
|
||||
$previewUserNames[] = Display::label($userInfo['complete_name']);
|
||||
}
|
||||
$previewTotal = array_merge($previewTotal, $previewUserNames);
|
||||
}
|
||||
|
||||
$previewTotal = array_map(function ($value) { return ''.$value; }, $previewTotal);
|
||||
|
||||
echo json_encode($previewTotal);
|
||||
break;
|
||||
case 'delete_item':
|
||||
if ($isAllowedToEdit) {
|
||||
if (empty($_REQUEST['id'])) {
|
||||
return false;
|
||||
}
|
||||
if (!empty($sessionId) && api_is_allowed_to_session_edit(false, true) == false && empty($groupId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$list = explode(',', $_REQUEST['id']);
|
||||
foreach ($list as $itemId) {
|
||||
if (!api_is_session_general_coach() || api_is_element_in_the_session(TOOL_ANNOUNCEMENT, $itemId)) {
|
||||
$result = AnnouncementManager::get_by_id(
|
||||
api_get_course_int_id(),
|
||||
$itemId
|
||||
);
|
||||
if (!empty($result)) {
|
||||
$delete = true;
|
||||
if (!empty($groupId) && $isTutor) {
|
||||
if ($groupId != $result['to_group_id']) {
|
||||
$delete = false;
|
||||
}
|
||||
}
|
||||
if ($delete) {
|
||||
AnnouncementManager::delete_announcement($courseInfo, $itemId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
echo '';
|
||||
break;
|
||||
}
|
||||
exit;
|
||||
22
main/inc/ajax/career.ajax.php
Normal file
22
main/inc/ajax/career.ajax.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Responses to AJAX calls.
|
||||
*/
|
||||
require_once __DIR__.'/../global.inc.php';
|
||||
|
||||
api_protect_admin_script();
|
||||
|
||||
$action = isset($_REQUEST['a']) ? $_REQUEST['a'] : null;
|
||||
|
||||
switch ($action) {
|
||||
case 'get_promotions':
|
||||
$careerId = isset($_REQUEST['career_id']) ? (int) $_REQUEST['career_id'] : 0;
|
||||
$career = new Promotion();
|
||||
$promotions = $career->get_all_promotions_by_career_id($careerId);
|
||||
echo json_encode($promotions);
|
||||
|
||||
break;
|
||||
}
|
||||
145
main/inc/ajax/chat.ajax.php
Normal file
145
main/inc/ajax/chat.ajax.php
Normal file
@@ -0,0 +1,145 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Responses to AJAX calls.
|
||||
*/
|
||||
$_dont_save_user_course_access = true;
|
||||
|
||||
require_once __DIR__.'/../global.inc.php';
|
||||
|
||||
api_block_anonymous_users();
|
||||
|
||||
if (api_get_setting('allow_global_chat') == 'false') {
|
||||
exit;
|
||||
}
|
||||
|
||||
$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : '';
|
||||
|
||||
// Course Chat
|
||||
if ($action === 'preview') {
|
||||
echo CourseChatUtils::prepareMessage($_REQUEST['message']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$toUserId = isset($_REQUEST['to']) ? $_REQUEST['to'] : null;
|
||||
$message = isset($_REQUEST['message']) ? $_REQUEST['message'] : null;
|
||||
$currentUserId = api_get_user_id();
|
||||
|
||||
$chat = new Chat();
|
||||
|
||||
if (Chat::disableChat()) {
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($chat->isChatBlockedByExercises()) {
|
||||
// Disconnecting the user
|
||||
$chat->setUserStatus(0);
|
||||
exit;
|
||||
}
|
||||
|
||||
switch ($action) {
|
||||
case 'get_message_status':
|
||||
$messageId = isset($_REQUEST['message_id']) ? $_REQUEST['message_id'] : 0;
|
||||
$messageInfo = $chat->get($messageId);
|
||||
if ($messageInfo && $messageInfo['from_user'] == $currentUserId) {
|
||||
echo json_encode($messageInfo);
|
||||
}
|
||||
break;
|
||||
case 'chatheartbeat':
|
||||
$chat->heartbeat();
|
||||
break;
|
||||
case 'close_window':
|
||||
// Closes friend window
|
||||
$chatId = isset($_POST['chatbox']) ? $_POST['chatbox'] : '';
|
||||
$chat->closeWindow($chatId);
|
||||
echo '1';
|
||||
exit;
|
||||
break;
|
||||
case 'close':
|
||||
// Disconnects user from all chat
|
||||
$chat->close();
|
||||
|
||||
echo '1';
|
||||
exit;
|
||||
break;
|
||||
case 'create_room':
|
||||
if (api_get_configuration_value('hide_chat_video')) {
|
||||
api_not_allowed();
|
||||
}
|
||||
/*$room = VideoChat::getChatRoomByUsers(api_get_user_id(), $toUserId);
|
||||
|
||||
if ($room === false) {
|
||||
$createdRoom = VideoChat::createRoom(api_get_user_id(), $toUserId);
|
||||
|
||||
if ($createdRoom === false) {
|
||||
echo Display::return_message(
|
||||
get_lang('ChatRoomNotCreated'),
|
||||
'error'
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
$room = VideoChat::getChatRoomByUsers(api_get_user_id(), $toUserId);
|
||||
}
|
||||
|
||||
$videoChatUrl = api_get_path(WEB_LIBRARY_JS_PATH)."chat/video.php?room={$room['id']}";
|
||||
$videoChatLink = Display::url(
|
||||
Display::returnFontAwesomeIcon('video-camera').get_lang('StartVideoChat'),
|
||||
$videoChatUrl
|
||||
);
|
||||
|
||||
$chat->send(
|
||||
api_get_user_id(),
|
||||
$toUserId,
|
||||
$videoChatLink,
|
||||
false,
|
||||
false
|
||||
);
|
||||
echo Display::tag('p', $videoChatLink, ['class' => 'lead']);*/
|
||||
break;
|
||||
case 'get_contacts':
|
||||
echo $chat->getContacts();
|
||||
break;
|
||||
case 'get_previous_messages':
|
||||
$userId = isset($_REQUEST['user_id']) ? $_REQUEST['user_id'] : 0;
|
||||
$visibleMessages = isset($_REQUEST['visible_messages']) ? $_REQUEST['visible_messages'] : 0;
|
||||
if (empty($userId)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$items = $chat->getPreviousMessages(
|
||||
$userId,
|
||||
$currentUserId,
|
||||
$visibleMessages
|
||||
);
|
||||
|
||||
if (!empty($items)) {
|
||||
sort($items);
|
||||
echo json_encode($items);
|
||||
exit;
|
||||
}
|
||||
echo json_encode([]);
|
||||
exit;
|
||||
break;
|
||||
case 'notify_not_support':
|
||||
$chat->send(
|
||||
$currentUserId,
|
||||
$toUserId,
|
||||
get_lang('TheXUserBrowserDoesNotSupportWebRTC')
|
||||
);
|
||||
break;
|
||||
case 'sendchat':
|
||||
$chat->send($currentUserId, $toUserId, $message);
|
||||
break;
|
||||
case 'startchatsession':
|
||||
$chat->startSession();
|
||||
break;
|
||||
case 'set_status':
|
||||
$status = isset($_REQUEST['status']) ? (int) $_REQUEST['status'] : 0;
|
||||
$chat->setUserStatus($status);
|
||||
break;
|
||||
default:
|
||||
echo '';
|
||||
}
|
||||
exit;
|
||||
421
main/inc/ajax/course.ajax.php
Normal file
421
main/inc/ajax/course.ajax.php
Normal file
@@ -0,0 +1,421 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use Chamilo\CoreBundle\Component\Utils\ChamiloApi;
|
||||
|
||||
/**
|
||||
* Responses to AJAX calls.
|
||||
*/
|
||||
require_once __DIR__.'/../global.inc.php';
|
||||
|
||||
$action = $_REQUEST['a'];
|
||||
$user_id = api_get_user_id();
|
||||
|
||||
switch ($action) {
|
||||
case 'add_course_vote':
|
||||
$course_id = (int) $_REQUEST['course_id'];
|
||||
$star = (int) $_REQUEST['star'];
|
||||
|
||||
if (!api_is_anonymous()) {
|
||||
CourseManager::add_course_vote($user_id, $star, $course_id, 0);
|
||||
}
|
||||
$point_info = CourseManager::get_course_ranking($course_id, 0);
|
||||
$ajax_url = api_get_path(WEB_AJAX_PATH).'course.ajax.php?a=add_course_vote';
|
||||
$rating = Display::return_rating_system(
|
||||
'star_'.$course_id,
|
||||
$ajax_url.'&course_id='.$course_id,
|
||||
$point_info,
|
||||
false
|
||||
);
|
||||
echo $rating;
|
||||
break;
|
||||
case 'get_course_image':
|
||||
$courseId = ChamiloApi::getCourseIdByDirectory($_REQUEST['code']);
|
||||
$courseInfo = api_get_course_info_by_id($courseId);
|
||||
$image = isset($_REQUEST['image']) && in_array($_REQUEST['image'], ['course_image_large_source', 'course_image_source', 'course_email_image_large_source', 'course_email_image_source']) ? $_REQUEST['image'] : '';
|
||||
if ($courseInfo && $image) {
|
||||
// Arbitrarily set a cache of 10' for the course image to
|
||||
// avoid hammering the server with otherwise unfrequently
|
||||
// changed images that can have some weight
|
||||
$now = time() + 600; //time must be in GMT anyway
|
||||
$headers = [
|
||||
'Expires' => gmdate('D, d M Y H:i:s ', $now).'GMT',
|
||||
'Cache-Control' => 'max-age=600',
|
||||
];
|
||||
DocumentManager::file_send_for_download($courseInfo[$image], null, null, null, $headers);
|
||||
}
|
||||
break;
|
||||
case 'get_user_courses':
|
||||
// Only search my courses
|
||||
if (api_is_platform_admin() || api_is_session_admin()) {
|
||||
$userId = (int) $_REQUEST['user_id'];
|
||||
$list = CourseManager::get_courses_list_by_user_id(
|
||||
$userId,
|
||||
false
|
||||
);
|
||||
if (!empty($list)) {
|
||||
foreach ($list as $course) {
|
||||
$courseInfo = api_get_course_info_by_id($course['real_id']);
|
||||
echo $courseInfo['title'].'<br />';
|
||||
}
|
||||
} else {
|
||||
echo get_lang('UserHasNoCourse');
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'get_my_courses_and_sessions':
|
||||
// Search my courses and sessions allowed for admin, session admin, teachers
|
||||
$currentCourseId = api_get_course_int_id();
|
||||
$currentSessionId = api_get_session_id();
|
||||
if (api_is_platform_admin() || api_is_session_admin() || api_is_allowed_to_edit()) {
|
||||
$list = CourseManager::get_courses_list_by_user_id(
|
||||
api_get_user_id(),
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
[],
|
||||
true,
|
||||
true
|
||||
);
|
||||
|
||||
if (empty($list)) {
|
||||
echo json_encode([]);
|
||||
break;
|
||||
}
|
||||
|
||||
$courseList = [];
|
||||
if (!empty($list)) {
|
||||
foreach ($list as $course) {
|
||||
$courseInfo = api_get_course_info_by_id($course['real_id']);
|
||||
$sessionId = 0;
|
||||
if (isset($course['session_id']) && !empty($course['session_id'])) {
|
||||
$sessionId = $course['session_id'];
|
||||
}
|
||||
|
||||
$sessionName = '';
|
||||
if (isset($course['session_name']) && !empty($course['session_name'])) {
|
||||
$sessionName = ' ('.$course['session_name'].')';
|
||||
}
|
||||
|
||||
// Skip current course/course session
|
||||
if ($currentCourseId == $courseInfo['real_id'] && $sessionId == $currentSessionId) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$courseList['items'][] = [
|
||||
'id' => $courseInfo['real_id'].'_'.$sessionId,
|
||||
'text' => $courseInfo['title'].$sessionName,
|
||||
];
|
||||
}
|
||||
|
||||
echo json_encode($courseList);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'search_category':
|
||||
if (api_is_platform_admin() || api_is_allowed_to_create_course()) {
|
||||
$categories = CourseCategory::searchCategoryByKeyword($_REQUEST['q']);
|
||||
|
||||
if (empty($categories)) {
|
||||
echo json_encode([]);
|
||||
break;
|
||||
}
|
||||
|
||||
$categoryToAvoid = '';
|
||||
if (!api_is_platform_admin()) {
|
||||
$categoryToAvoid = api_get_configuration_value('course_category_code_to_use_as_model');
|
||||
}
|
||||
|
||||
$list = [];
|
||||
foreach ($categories as $item) {
|
||||
$categoryCode = $item['code'];
|
||||
if (!empty($categoryToAvoid) && $categoryToAvoid == $categoryCode) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$list['items'][] = [
|
||||
'id' => $categoryCode,
|
||||
'text' => '('.$categoryCode.') '.strip_tags($item['name']),
|
||||
];
|
||||
}
|
||||
|
||||
echo json_encode($list);
|
||||
}
|
||||
break;
|
||||
case 'search_course':
|
||||
if (api_is_teacher() || api_is_platform_admin()) {
|
||||
if (isset($_GET['session_id']) && !empty($_GET['session_id'])) {
|
||||
//if session is defined, lets find only courses of this session
|
||||
$courseList = SessionManager::get_course_list_by_session_id(
|
||||
$_GET['session_id'],
|
||||
$_GET['q']
|
||||
);
|
||||
} else {
|
||||
//if session is not defined lets search all courses STARTING with $_GET['q']
|
||||
//TODO change this function to search not only courses STARTING with $_GET['q']
|
||||
if (api_is_platform_admin()) {
|
||||
$courseList = CourseManager::get_courses_list(
|
||||
0,
|
||||
0,
|
||||
'title',
|
||||
'ASC',
|
||||
-1,
|
||||
$_GET['q'],
|
||||
null,
|
||||
true
|
||||
);
|
||||
} elseif (api_is_teacher()) {
|
||||
$courseList = CourseManager::get_course_list_of_user_as_course_admin(api_get_user_id(), $_GET['q']);
|
||||
$category = api_get_configuration_value('course_category_code_to_use_as_model');
|
||||
if (!empty($category)) {
|
||||
$alreadyAdded = [];
|
||||
if (!empty($courseList)) {
|
||||
$alreadyAdded = array_column($courseList, 'id');
|
||||
}
|
||||
$coursesInCategory = CourseCategory::getCoursesInCategory($category, $_GET['q']);
|
||||
foreach ($coursesInCategory as $course) {
|
||||
if (!in_array($course['id'], $alreadyAdded)) {
|
||||
$courseList[] = $course;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$results = [];
|
||||
if (empty($courseList)) {
|
||||
echo json_encode([]);
|
||||
break;
|
||||
}
|
||||
|
||||
foreach ($courseList as $course) {
|
||||
$title = $course['title'];
|
||||
if (!empty($course['category_code'])) {
|
||||
$parents = CourseCategory::getParentsToString($course['category_code']);
|
||||
$title = $parents.$course['title'];
|
||||
}
|
||||
|
||||
$results['items'][] = [
|
||||
'id' => $course['id'],
|
||||
'text' => $title,
|
||||
];
|
||||
}
|
||||
|
||||
echo json_encode($results);
|
||||
}
|
||||
break;
|
||||
case 'search_course_by_session':
|
||||
if (api_is_platform_admin()) {
|
||||
$results = SessionManager::get_course_list_by_session_id($_GET['session_id'], $_GET['q']);
|
||||
$results2 = [];
|
||||
if (is_array($results) && !empty($results)) {
|
||||
foreach ($results as $item) {
|
||||
$item2 = [];
|
||||
foreach ($item as $id => $internal) {
|
||||
if ($id == 'id') {
|
||||
$item2[$id] = $internal;
|
||||
}
|
||||
if ($id == 'title') {
|
||||
$item2['text'] = $internal;
|
||||
}
|
||||
}
|
||||
$results2[] = $item2;
|
||||
}
|
||||
echo json_encode($results2);
|
||||
} else {
|
||||
echo json_encode([]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'search_course_by_session_all':
|
||||
if (api_is_platform_admin()) {
|
||||
if ($_GET['session_id'] == 'TODOS' || $_GET['session_id'] == 'T') {
|
||||
$_GET['session_id'] = '%';
|
||||
}
|
||||
|
||||
$results = SessionManager::get_course_list_by_session_id_like(
|
||||
$_GET['session_id'],
|
||||
$_GET['q']
|
||||
);
|
||||
$results2 = ['items' => []];
|
||||
if (!empty($results)) {
|
||||
foreach ($results as $item) {
|
||||
$item2 = [];
|
||||
foreach ($item as $id => $internal) {
|
||||
if ($id == 'id') {
|
||||
$item2[$id] = $internal;
|
||||
}
|
||||
if ($id == 'title') {
|
||||
$item2['text'] = $internal;
|
||||
}
|
||||
}
|
||||
$results2['items'][] = $item2;
|
||||
}
|
||||
}
|
||||
|
||||
echo json_encode($results2);
|
||||
}
|
||||
break;
|
||||
case 'search_user_by_course':
|
||||
$sessionId = $_GET['session_id'];
|
||||
$course = api_get_course_info_by_id($_GET['course_id']);
|
||||
|
||||
$isPlatformAdmin = api_is_platform_admin();
|
||||
$userIsSubscribedInCourse = CourseManager::is_user_subscribed_in_course(
|
||||
api_get_user_id(),
|
||||
$course['code'],
|
||||
!empty($sessionId),
|
||||
$sessionId
|
||||
);
|
||||
|
||||
if ($isPlatformAdmin || $userIsSubscribedInCourse) {
|
||||
$json = [
|
||||
'items' => [],
|
||||
];
|
||||
|
||||
$keyword = Database::escape_string($_GET['q']);
|
||||
$status = 0;
|
||||
if (empty($sessionId)) {
|
||||
$status = STUDENT;
|
||||
}
|
||||
|
||||
$userList = CourseManager::get_user_list_from_course_code(
|
||||
$course['code'],
|
||||
$sessionId,
|
||||
null,
|
||||
null,
|
||||
$status,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
true,
|
||||
[],
|
||||
$_GET['q']
|
||||
);
|
||||
|
||||
foreach ($userList as $user) {
|
||||
$userCompleteName = api_get_person_name($user['firstname'], $user['lastname']);
|
||||
|
||||
$json['items'][] = [
|
||||
'id' => $user['user_id'],
|
||||
'text' => "{$user['username']} ($userCompleteName)",
|
||||
'avatarUrl' => UserManager::getUserPicture($user['id']),
|
||||
'username' => $user['username'],
|
||||
'completeName' => $userCompleteName,
|
||||
];
|
||||
}
|
||||
|
||||
echo json_encode($json);
|
||||
}
|
||||
break;
|
||||
case 'search_exercise_by_course':
|
||||
if (api_is_platform_admin()) {
|
||||
$course = api_get_course_info_by_id($_GET['course_id']);
|
||||
$session_id = (!empty($_GET['session_id'])) ? (int) $_GET['session_id'] : 0;
|
||||
$exercises = ExerciseLib::get_all_exercises(
|
||||
$course,
|
||||
$session_id,
|
||||
false,
|
||||
$_GET['q'],
|
||||
true,
|
||||
3
|
||||
);
|
||||
|
||||
foreach ($exercises as $exercise) {
|
||||
$data[] = ['id' => $exercise['iid'], 'text' => html_entity_decode($exercise['title'])];
|
||||
}
|
||||
if (!empty($data)) {
|
||||
$data[] = ['id' => 'T', 'text' => 'TODOS'];
|
||||
echo json_encode($data);
|
||||
} else {
|
||||
echo json_encode([['id' => 'T', 'text' => 'TODOS']]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'search_survey_by_course':
|
||||
if (api_is_platform_admin()) {
|
||||
$survey = Database::get_course_table(TABLE_SURVEY);
|
||||
|
||||
$sql = "SELECT survey_id as id, title, anonymous
|
||||
FROM $survey
|
||||
WHERE
|
||||
c_id = %d AND
|
||||
session_id = %d AND
|
||||
title LIKE '%s'";
|
||||
|
||||
$sql_query = sprintf(
|
||||
$sql,
|
||||
(int) $_GET['course_id'],
|
||||
(int) $_GET['session_id'],
|
||||
'%'.Database::escape_string($_GET['q']).'%'
|
||||
);
|
||||
$result = Database::query($sql_query);
|
||||
while ($survey = Database::fetch_assoc($result)) {
|
||||
$survey['title'] .= ($survey['anonymous'] == 1) ? ' ('.get_lang('Anonymous').')' : '';
|
||||
$data[] = [
|
||||
'id' => $survey['id'],
|
||||
'text' => strip_tags(html_entity_decode($survey['title'])),
|
||||
];
|
||||
}
|
||||
if (!empty($data)) {
|
||||
echo json_encode($data);
|
||||
} else {
|
||||
echo json_encode([]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'display_sessions_courses':
|
||||
$sessionId = (int) $_GET['session'];
|
||||
$userTable = Database::get_main_table(TABLE_MAIN_USER);
|
||||
$coursesData = SessionManager::get_course_list_by_session_id($sessionId);
|
||||
|
||||
$courses = [];
|
||||
|
||||
foreach ($coursesData as $courseId => $course) {
|
||||
$coachData = SessionManager::getCoachesByCourseSession($sessionId, $courseId);
|
||||
$coachName = '';
|
||||
if (!empty($coachData)) {
|
||||
$userResult = Database::select('lastname,firstname', $userTable, [
|
||||
'where' => [
|
||||
'user_id = ?' => $coachData[0],
|
||||
],
|
||||
], 'first');
|
||||
|
||||
$coachName = api_get_person_name($userResult['firstname'], $userResult['lastname']);
|
||||
}
|
||||
|
||||
$courses[] = [
|
||||
'id' => $courseId,
|
||||
'name' => $course['title'],
|
||||
'coachName' => $coachName,
|
||||
];
|
||||
}
|
||||
|
||||
echo json_encode($courses);
|
||||
break;
|
||||
case 'course_logout':
|
||||
$logoutInfo = [
|
||||
'uid' => api_get_user_id(),
|
||||
'cid' => api_get_course_int_id(),
|
||||
'sid' => api_get_session_id(),
|
||||
];
|
||||
|
||||
$logInfo = [
|
||||
'tool' => 'close-window',
|
||||
'tool_id' => 0,
|
||||
'tool_id_detail' => 0,
|
||||
'action' => 'exit',
|
||||
];
|
||||
Event::registerLog($logInfo);
|
||||
|
||||
$result = (int) Event::courseLogout($logoutInfo);
|
||||
echo $result;
|
||||
break;
|
||||
default:
|
||||
echo '';
|
||||
}
|
||||
exit;
|
||||
43
main/inc/ajax/course_category.ajax.php
Normal file
43
main/inc/ajax/course_category.ajax.php
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Responses to AJAX calls.
|
||||
*/
|
||||
require_once __DIR__.'/../global.inc.php';
|
||||
|
||||
api_protect_admin_script();
|
||||
|
||||
$action = $_REQUEST['a'];
|
||||
|
||||
switch ($action) {
|
||||
case 'show_courses':
|
||||
$categoryId = (int) $_REQUEST['id'];
|
||||
$categoryInfo = CourseCategory::getCategoryById($categoryId);
|
||||
if (!empty($categoryInfo)) {
|
||||
$courses = CourseCategory::getCoursesInCategory($categoryInfo['code'], '', false, false);
|
||||
|
||||
$table = new HTML_Table(['class' => 'table table-hover table-striped data_table']);
|
||||
$headers = [
|
||||
get_lang('Name'),
|
||||
];
|
||||
$row = 0;
|
||||
$column = 0;
|
||||
foreach ($headers as $header) {
|
||||
$table->setHeaderContents($row, $column, $header);
|
||||
$column++;
|
||||
}
|
||||
$result = '';
|
||||
foreach ($courses as $course) {
|
||||
$row++;
|
||||
$courseLink = '<a href="'.api_get_path(WEB_PATH).'courses/'.$course['directory'].'/index.php">'.$course['title'].'</a>';
|
||||
$table->setCellContents($row, 0, $courseLink);
|
||||
}
|
||||
|
||||
echo $table->toHtml();
|
||||
exit;
|
||||
}
|
||||
break;
|
||||
}
|
||||
exit;
|
||||
98
main/inc/ajax/course_chat.ajax.php
Normal file
98
main/inc/ajax/course_chat.ajax.php
Normal file
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
/**
|
||||
* Responses to AJAX calls for course chat.
|
||||
*/
|
||||
|
||||
use Symfony\Component\HttpFoundation\JsonResponse as HttpResponse;
|
||||
use Symfony\Component\HttpFoundation\Request as HttpRequest;
|
||||
|
||||
require_once __DIR__.'/../global.inc.php';
|
||||
|
||||
if (!api_protect_course_script(false)) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$courseId = api_get_course_int_id();
|
||||
$userId = api_get_user_id();
|
||||
$sessionId = api_get_session_id();
|
||||
$groupId = api_get_group_id();
|
||||
$json = ['status' => false];
|
||||
|
||||
$httpRequest = HttpRequest::createFromGlobals();
|
||||
$httpResponse = HttpResponse::create();
|
||||
|
||||
$courseChatUtils = new CourseChatUtils($courseId, $userId, $sessionId, $groupId);
|
||||
|
||||
$token = Security::getTokenFromSession('course_chat');
|
||||
|
||||
if ($httpRequest->headers->get('x-token') !== $token) {
|
||||
$_REQUEST['action'] = 'error';
|
||||
}
|
||||
|
||||
switch ($_REQUEST['action']) {
|
||||
case 'chat_logout':
|
||||
$logInfo = [
|
||||
'tool' => TOOL_CHAT,
|
||||
'action' => 'exit',
|
||||
'action_details' => 'exit-chat',
|
||||
];
|
||||
Event::registerLog($logInfo);
|
||||
break;
|
||||
case 'track':
|
||||
$courseChatUtils->keepUserAsConnected();
|
||||
$courseChatUtils->disconnectInactiveUsers();
|
||||
|
||||
$friend = isset($_REQUEST['friend']) ? (int) $_REQUEST['friend'] : 0;
|
||||
$filePath = $courseChatUtils->getFileName(true, $friend);
|
||||
$newFileSize = file_exists($filePath) ? filesize($filePath) : 0;
|
||||
$oldFileSize = isset($_GET['size']) ? (int) $_GET['size'] : -1;
|
||||
$newUsersOnline = $courseChatUtils->countUsersOnline();
|
||||
$oldUsersOnline = isset($_GET['users_online']) ? (int) $_GET['users_online'] : 0;
|
||||
|
||||
$json = [
|
||||
'status' => true,
|
||||
'data' => [
|
||||
'oldFileSize' => file_exists($filePath) ? filesize($filePath) : 0,
|
||||
'history' => $newFileSize !== $oldFileSize ? $courseChatUtils->readMessages(false, $friend) : null,
|
||||
'usersOnline' => $newUsersOnline,
|
||||
'userList' => $newUsersOnline != $oldUsersOnline ? $courseChatUtils->listUsersOnline() : null,
|
||||
'currentFriend' => $friend,
|
||||
],
|
||||
];
|
||||
|
||||
break;
|
||||
case 'preview':
|
||||
$json = [
|
||||
'status' => true,
|
||||
'data' => [
|
||||
'message' => CourseChatUtils::prepareMessage($_REQUEST['message']),
|
||||
],
|
||||
];
|
||||
break;
|
||||
case 'reset':
|
||||
$friend = isset($_REQUEST['friend']) ? (int) $_REQUEST['friend'] : 0;
|
||||
|
||||
$json = [
|
||||
'status' => true,
|
||||
'data' => $courseChatUtils->readMessages(true, $friend),
|
||||
];
|
||||
break;
|
||||
case 'write':
|
||||
$friend = isset($_REQUEST['friend']) ? (int) $_REQUEST['friend'] : 0;
|
||||
$writed = $courseChatUtils->saveMessage($_POST['message'], $friend);
|
||||
|
||||
$json = [
|
||||
'status' => $writed,
|
||||
'data' => [
|
||||
'writed' => $writed,
|
||||
],
|
||||
];
|
||||
break;
|
||||
}
|
||||
|
||||
$token = Security::get_token('course_chat');
|
||||
|
||||
$httpResponse->headers->set('x-token', $token);
|
||||
$httpResponse->setData($json);
|
||||
$httpResponse->send();
|
||||
754
main/inc/ajax/course_home.ajax.php
Normal file
754
main/inc/ajax/course_home.ajax.php
Normal file
@@ -0,0 +1,754 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use Chamilo\CourseBundle\Entity\CTool;
|
||||
use ChamiloSession as Session;
|
||||
|
||||
// @todo refactor this script, create a class that manage the jqgrid requests
|
||||
/**
|
||||
* Responses to AJAX calls.
|
||||
*/
|
||||
$action = $_GET['a'];
|
||||
|
||||
switch ($action) {
|
||||
case 'set_visibility':
|
||||
require_once __DIR__.'/../global.inc.php';
|
||||
$course_id = api_get_course_int_id();
|
||||
$sessionId = api_get_session_id();
|
||||
// Allow tool visibility in sessions.
|
||||
$allowEditionInSession = api_get_configuration_value('allow_edit_tool_visibility_in_session');
|
||||
$em = Database::getManager();
|
||||
$repository = $em->getRepository('ChamiloCourseBundle:CTool');
|
||||
if (api_is_allowed_to_edit(null, true)) {
|
||||
$criteria = [
|
||||
'cId' => $course_id,
|
||||
//'sessionId' => 0,
|
||||
'iid' => (int) $_GET['id'],
|
||||
];
|
||||
|
||||
/** @var CTool $tool */
|
||||
$tool = $repository->findOneBy($criteria);
|
||||
$visibility = 0;
|
||||
if ($allowEditionInSession && !empty($sessionId)) {
|
||||
$newLink = str_replace('id_session=0', 'id_session='.$sessionId, $tool->getLink());
|
||||
$criteria = [
|
||||
'cId' => $course_id,
|
||||
'sessionId' => $sessionId,
|
||||
//'iid' => (int) $_GET['id'],
|
||||
'link' => $newLink,
|
||||
];
|
||||
|
||||
/** @var CTool $tool */
|
||||
$toolInSession = $repository->findOneBy($criteria);
|
||||
if ($toolInSession) {
|
||||
// Use the session
|
||||
$tool = $toolInSession;
|
||||
$visibility = $toolInSession->getVisibility();
|
||||
} else {
|
||||
// Creates new row in c_tool
|
||||
$toolInSession = clone $tool;
|
||||
$toolInSession->setLink($newLink);
|
||||
$toolInSession->setIid(0);
|
||||
$toolInSession->setId(0);
|
||||
$toolInSession->setVisibility(0);
|
||||
$toolInSession->setSessionId($sessionId);
|
||||
$em->persist($toolInSession);
|
||||
$em->flush();
|
||||
// Update id with iid
|
||||
$toolInSession->setId($toolInSession->getIid());
|
||||
$em->persist($toolInSession);
|
||||
$em->flush();
|
||||
// $tool will be updated later
|
||||
$tool = $toolInSession;
|
||||
}
|
||||
} else {
|
||||
$visibility = $tool->getVisibility();
|
||||
}
|
||||
|
||||
$toolImage = $tool->getImage();
|
||||
$customIcon = $tool->getCustomIcon();
|
||||
|
||||
if (api_get_setting('homepage_view') !== 'activity_big') {
|
||||
$toolImage = Display::return_icon(
|
||||
$toolImage,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
true
|
||||
);
|
||||
$inactiveImage = str_replace('.gif', '_na.gif', $toolImage);
|
||||
} else {
|
||||
// Display::return_icon() also checks in the app/Resources/public/css/themes/{theme}/icons folder
|
||||
$toolImage = (substr($toolImage, 0, strpos($toolImage, '.'))).'.png';
|
||||
$toolImage = Display::return_icon(
|
||||
$toolImage,
|
||||
get_lang(ucfirst($tool->getName())),
|
||||
null,
|
||||
ICON_SIZE_BIG,
|
||||
null,
|
||||
true
|
||||
);
|
||||
$inactiveImage = str_replace('.png', '_na.png', $toolImage);
|
||||
}
|
||||
|
||||
if (isset($customIcon) && !empty($customIcon)) {
|
||||
$toolImage = CourseHome::getCustomWebIconPath().$customIcon;
|
||||
$inactiveImage = CourseHome::getCustomWebIconPath().CourseHome::getDisableIcon($customIcon);
|
||||
}
|
||||
|
||||
$requested_image = $visibility == 0 ? $toolImage : $inactiveImage;
|
||||
$requested_class = $visibility == 0 ? '' : 'text-muted';
|
||||
$requested_message = $visibility == 0 ? 'is_active' : 'is_inactive';
|
||||
$requested_view = $visibility == 0 ? 'visible.png' : 'invisible.png';
|
||||
$requestedVisible = $visibility == 0 ? 1 : 0;
|
||||
$requested_view = $visibility == 0 ? 'visible.png' : 'invisible.png';
|
||||
$requestedVisible = $visibility == 0 ? 1 : 0;
|
||||
$requested_fa_class = $visibility == 0 ? 'fa fa-eye '.$requested_class : 'fa fa-eye-slash '.$requested_class;
|
||||
|
||||
// HIDE AND REACTIVATE TOOL
|
||||
if ($_GET['id'] == strval(intval($_GET['id']))) {
|
||||
$tool->setVisibility($requestedVisible);
|
||||
$em->persist($tool);
|
||||
$em->flush();
|
||||
|
||||
// Also hide the tool in all sessions
|
||||
if ($allowEditionInSession && empty($sessionId)) {
|
||||
$criteria = [
|
||||
'cId' => $course_id,
|
||||
'name' => $tool->getName(),
|
||||
];
|
||||
|
||||
/** @var CTool $toolItem */
|
||||
$tools = $repository->findBy($criteria);
|
||||
foreach ($tools as $toolItem) {
|
||||
$toolSessionId = $toolItem->getSessionId();
|
||||
if (!empty($toolSessionId)) {
|
||||
$toolItem->setVisibility($requestedVisible);
|
||||
$em->persist($toolItem);
|
||||
}
|
||||
}
|
||||
$em->flush();
|
||||
}
|
||||
}
|
||||
|
||||
$response = [
|
||||
'image' => $requested_image,
|
||||
'tclass' => $requested_class,
|
||||
'message' => $requested_message,
|
||||
'view' => $requested_view,
|
||||
'fclass' => $requested_fa_class,
|
||||
];
|
||||
echo json_encode($response);
|
||||
}
|
||||
break;
|
||||
case 'set_visibility_for_all':
|
||||
require_once __DIR__.'/../global.inc.php';
|
||||
$course_id = api_get_course_int_id();
|
||||
$sessionId = api_get_session_id();
|
||||
$allowEditionInSession = api_get_configuration_value('allow_edit_tool_visibility_in_session');
|
||||
$response = [];
|
||||
$tools_ids = json_decode($_GET['tools_ids']);
|
||||
$em = Database::getManager();
|
||||
$repository = $em->getRepository('ChamiloCourseBundle:CTool');
|
||||
// Allow tool visibility in sessions.
|
||||
if (api_is_allowed_to_edit(null, true)) {
|
||||
if (is_array($tools_ids) && count($tools_ids) != 0) {
|
||||
$total_tools = count($tools_ids);
|
||||
for ($i = 0; $i < $total_tools; $i++) {
|
||||
$tool_id = (int) $tools_ids[$i];
|
||||
|
||||
$criteria = [
|
||||
'cId' => $course_id,
|
||||
'sessionId' => 0,
|
||||
'iid' => $tool_id,
|
||||
];
|
||||
/** @var CTool $tool */
|
||||
$tool = $repository->findOneBy($criteria);
|
||||
$visibility = $tool->getVisibility();
|
||||
|
||||
if ($allowEditionInSession && !empty($sessionId)) {
|
||||
$criteria = [
|
||||
'cId' => $course_id,
|
||||
'sessionId' => $sessionId,
|
||||
'name' => $tool->getName(),
|
||||
];
|
||||
|
||||
/** @var CTool $tool */
|
||||
$toolInSession = $repository->findOneBy($criteria);
|
||||
if ($toolInSession) {
|
||||
// Use the session
|
||||
$tool = $toolInSession;
|
||||
$visibility = $toolInSession->getVisibility();
|
||||
} else {
|
||||
// Creates new row in c_tool
|
||||
$toolInSession = clone $tool;
|
||||
$toolInSession->setIid(0);
|
||||
$toolInSession->setId(0);
|
||||
$toolInSession->setVisibility(0);
|
||||
$toolInSession->setSessionId($session_id);
|
||||
$em->persist($toolInSession);
|
||||
$em->flush();
|
||||
// Update id with iid
|
||||
$toolInSession->setId($toolInSession->getIid());
|
||||
$em->persist($toolInSession);
|
||||
$em->flush();
|
||||
// $tool will be updated later
|
||||
$tool = $toolInSession;
|
||||
}
|
||||
}
|
||||
|
||||
$toolImage = $tool->getImage();
|
||||
$customIcon = $tool->getCustomIcon();
|
||||
|
||||
if (api_get_setting('homepage_view') != 'activity_big') {
|
||||
$toolImage = Display::return_icon(
|
||||
$toolImage,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
true
|
||||
);
|
||||
$inactiveImage = str_replace('.gif', '_na.gif', $toolImage);
|
||||
} else {
|
||||
// Display::return_icon() also checks in the app/Resources/public/css/themes/{theme}/icons folder
|
||||
$toolImage = (substr($toolImage, 0, strpos($toolImage, '.'))).'.png';
|
||||
$toolImage = Display::return_icon(
|
||||
$toolImage,
|
||||
get_lang(ucfirst($tool->getName())),
|
||||
null,
|
||||
ICON_SIZE_BIG,
|
||||
null,
|
||||
true
|
||||
);
|
||||
$inactiveImage = str_replace('.png', '_na.png', $toolImage);
|
||||
}
|
||||
|
||||
if (isset($customIcon) && !empty($customIcon)) {
|
||||
$toolImage = CourseHome::getCustomWebIconPath().$customIcon;
|
||||
$inactiveImage = CourseHome::getCustomWebIconPath().CourseHome::getDisableIcon($customIcon);
|
||||
}
|
||||
|
||||
$requested_image = $visibility == 0 ? $toolImage : $inactiveImage;
|
||||
$requested_class = $visibility == 0 ? '' : 'text-muted';
|
||||
$requested_message = $visibility == 0 ? 'is_active' : 'is_inactive';
|
||||
$requested_view = $visibility == 0 ? 'visible.png' : 'invisible.png';
|
||||
$requestedVisible = $visibility == 0 ? 1 : 0;
|
||||
$requested_view = $visibility == 0 ? 'visible.png' : 'invisible.png';
|
||||
$requested_fa_class = $visibility == 0 ? 'fa fa-eye '.$requested_class : 'fa fa-eye-slash '.$requested_class;
|
||||
$requestedVisible = $visibility == 0 ? 1 : 0;
|
||||
|
||||
// HIDE AND REACTIVATE TOOL
|
||||
if ($tool_id == strval(intval($tool_id))) {
|
||||
$tool->setVisibility($requestedVisible);
|
||||
$em->persist($tool);
|
||||
$em->flush();
|
||||
|
||||
// Also hide the tool in all sessions
|
||||
if ($allowEditionInSession && empty($sessionId)) {
|
||||
$criteria = [
|
||||
'cId' => $course_id,
|
||||
'name' => $tool->getName(),
|
||||
];
|
||||
|
||||
/** @var CTool $toolItem */
|
||||
$tools = $repository->findBy($criteria);
|
||||
foreach ($tools as $toolItem) {
|
||||
$toolSessionId = $toolItem->getSessionId();
|
||||
if (!empty($toolSessionId)) {
|
||||
$toolItem->setVisibility($requestedVisible);
|
||||
$em->persist($toolItem);
|
||||
}
|
||||
}
|
||||
$em->flush();
|
||||
}
|
||||
}
|
||||
$response[] = [
|
||||
'image' => $requested_image,
|
||||
'tclass' => $requested_class,
|
||||
'message' => $requested_message,
|
||||
'view' => $requested_view,
|
||||
'fclass' => $requested_fa_class,
|
||||
'id' => $tool_id,
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
echo json_encode($response);
|
||||
break;
|
||||
case 'show_course_information':
|
||||
require_once __DIR__.'/../global.inc.php';
|
||||
|
||||
// Get the name of the database course.
|
||||
$course_info = api_get_course_info($_GET['code']);
|
||||
$content = get_lang('NoDescription');
|
||||
if (!empty($course_info)) {
|
||||
if (api_get_setting('course_catalog_hide_private') === 'true' &&
|
||||
$course_info['visibility'] == COURSE_VISIBILITY_REGISTERED
|
||||
) {
|
||||
echo get_lang('PrivateAccess');
|
||||
break;
|
||||
}
|
||||
$table = Database::get_course_table(TABLE_COURSE_DESCRIPTION);
|
||||
$sql = "SELECT * FROM $table
|
||||
WHERE c_id = ".$course_info['real_id']." AND session_id = 0
|
||||
ORDER BY id";
|
||||
$result = Database::query($sql);
|
||||
if (Database::num_rows($result) > 0) {
|
||||
while ($description = Database::fetch_object($result)) {
|
||||
$descriptions[$description->id] = $description;
|
||||
}
|
||||
// Function that displays the details of the course description in html.
|
||||
$content = CourseManager::get_details_course_description_html(
|
||||
$descriptions,
|
||||
api_get_system_encoding(),
|
||||
false
|
||||
);
|
||||
}
|
||||
}
|
||||
echo $content;
|
||||
break;
|
||||
case 'session_courses_lp_default':
|
||||
/**
|
||||
* @todo this functions need to belong to a class or a special
|
||||
* wrapper to process the AJAX petitions from the jqgrid
|
||||
*/
|
||||
require_once __DIR__.'/../global.inc.php';
|
||||
$now = time();
|
||||
$page = (int) $_REQUEST['page']; //page
|
||||
$limit = (int) $_REQUEST['rows']; // quantity of rows
|
||||
//index to filter
|
||||
$sidx = isset($_REQUEST['sidx']) && !empty($_REQUEST['sidx']) ? $_REQUEST['sidx'] : 'id';
|
||||
$sord = $_REQUEST['sord']; //asc or desc
|
||||
if (!in_array($sord, ['asc', 'desc'])) {
|
||||
$sord = 'desc';
|
||||
}
|
||||
$session_id = (int) $_REQUEST['session_id'];
|
||||
$course_id = (int) $_REQUEST['course_id'];
|
||||
|
||||
//Filter users that does not belong to the session
|
||||
if (!api_is_platform_admin()) {
|
||||
$new_session_list = UserManager::get_personal_session_course_list(api_get_user_id());
|
||||
$my_session_list = [];
|
||||
foreach ($new_session_list as $item) {
|
||||
if (!empty($item['session_id'])) {
|
||||
$my_session_list[] = $item['session_id'];
|
||||
}
|
||||
}
|
||||
if (!in_array($session_id, $my_session_list)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$start = $limit * $page - $limit;
|
||||
$course_list = SessionManager::get_course_list_by_session_id($session_id);
|
||||
$count = 0;
|
||||
$temp = [];
|
||||
foreach ($course_list as $item) {
|
||||
$courseInfo = api_get_course_info($item['code']);
|
||||
$list = new LearnpathList(api_get_user_id(), $courseInfo, $session_id);
|
||||
$flat_list = $list->get_flat_list();
|
||||
$lps[$item['code']] = $flat_list;
|
||||
$course_url = api_get_path(WEB_COURSE_PATH).$item['directory'].'/?id_session='.$session_id;
|
||||
$item['title'] = Display::url($item['title'], $course_url, ['target' => SESSION_LINK_TARGET]);
|
||||
|
||||
foreach ($flat_list as $lp_id => $lp_item) {
|
||||
$isAllowedToEdit = api_is_allowed_to_edit(null, true);
|
||||
|
||||
if (!$isAllowedToEdit && 0 == $lp_item['lp_visibility']) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$temp[$count]['id'] = $lp_id;
|
||||
|
||||
$lp = new learnpath($item['code'], $lp_id, api_get_user_id());
|
||||
if ($lp->progress_db == 100) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$lp_url = api_get_path(WEB_CODE_PATH).'lp/lp_controller.php?cidReq='.$item['code'].'&id_session='.$session_id.'&lp_id='.$lp_id.'&action=view';
|
||||
|
||||
$last_date = Tracking::get_last_connection_date_on_the_course(
|
||||
api_get_user_id(),
|
||||
$item,
|
||||
$session_id,
|
||||
false
|
||||
);
|
||||
|
||||
if (empty($lp_item['modified_on'])) {
|
||||
$lp_date = api_get_local_time($lp_item['created_on']);
|
||||
$image = 'new.gif';
|
||||
$label = get_lang('LearnpathAdded');
|
||||
} else {
|
||||
$lp_date = api_get_local_time($lp_item['modified_on']);
|
||||
$image = 'moderator_star.png';
|
||||
$label = get_lang('LearnpathUpdated');
|
||||
}
|
||||
|
||||
$icons = '';
|
||||
if (strtotime($last_date) < strtotime($lp_date)) {
|
||||
$icons = Display::return_icon($image, get_lang('TitleNotification').': '.$label.' - '.$lp_date);
|
||||
}
|
||||
|
||||
if (!empty($lp_item['publicated_on'])) {
|
||||
$date = substr($lp_item['publicated_on'], 0, 10);
|
||||
} else {
|
||||
$date = '-';
|
||||
}
|
||||
|
||||
// Checking LP publicated and expired_on dates
|
||||
if (!empty($lp_item['publicated_on'])) {
|
||||
if ($now < api_strtotime($lp_item['publicated_on'], 'UTC')) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($lp_item['expired_on'])) {
|
||||
if ($now > api_strtotime($lp_item['expired_on'], 'UTC')) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$temp[$count]['cell'] = [
|
||||
$date,
|
||||
$item['title'],
|
||||
Display::url($icons.' '.$lp_item['lp_name'], $lp_url, ['target' => SESSION_LINK_TARGET]),
|
||||
];
|
||||
$temp[$count]['course'] = strip_tags($item['title']);
|
||||
$temp[$count]['lp'] = $lp_item['lp_name'];
|
||||
$temp[$count]['date'] = $lp_item['publicated_on'];
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
$temp = msort($temp, $sidx, $sord);
|
||||
|
||||
$i = 0;
|
||||
$response = new stdClass();
|
||||
foreach ($temp as $key => $row) {
|
||||
$row = $row['cell'];
|
||||
if (!empty($row)) {
|
||||
if ($key >= $start && $key < ($start + $limit)) {
|
||||
$response->rows[$i]['id'] = $key;
|
||||
$response->rows[$i]['cell'] = [$row[0], $row[1], $row[2]];
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
$total_pages = 0;
|
||||
if ($count > 0 && $limit > 0) {
|
||||
$total_pages = ceil($count / $limit);
|
||||
}
|
||||
$response->total = $total_pages;
|
||||
if ($page > $total_pages) {
|
||||
$response->page = $total_pages;
|
||||
} else {
|
||||
$response->page = $page;
|
||||
}
|
||||
$response->records = $count;
|
||||
echo json_encode($response);
|
||||
break;
|
||||
case 'session_courses_lp_by_week':
|
||||
require_once __DIR__.'/../global.inc.php';
|
||||
$now = time();
|
||||
$page = (int) $_REQUEST['page']; //page
|
||||
$limit = (int) $_REQUEST['rows']; // quantity of rows
|
||||
$sidx = isset($_REQUEST['sidx']) && !empty($_REQUEST['sidx']) ? $_REQUEST['sidx'] : 'course';
|
||||
$sidx = str_replace(['week desc,', ' '], '', $sidx);
|
||||
$sord = $_REQUEST['sord']; //asc or desc
|
||||
if (!in_array($sord, ['asc', 'desc'])) {
|
||||
$sord = 'desc';
|
||||
}
|
||||
|
||||
$session_id = (int) $_REQUEST['session_id'];
|
||||
$course_id = (int) $_REQUEST['course_id'];
|
||||
|
||||
//Filter users that does not belong to the session
|
||||
if (!api_is_platform_admin()) {
|
||||
$new_session_list = UserManager::get_personal_session_course_list(api_get_user_id());
|
||||
$my_session_list = [];
|
||||
foreach ($new_session_list as $item) {
|
||||
if (!empty($item['session_id'])) {
|
||||
$my_session_list[] = $item['session_id'];
|
||||
}
|
||||
}
|
||||
if (!in_array($session_id, $my_session_list)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$start = $limit * $page - $limit;
|
||||
$course_list = SessionManager::get_course_list_by_session_id($session_id);
|
||||
|
||||
$count = 0;
|
||||
$temp = [];
|
||||
foreach ($course_list as $item) {
|
||||
if (isset($course_id) && !empty($course_id)) {
|
||||
if ($course_id != $item['id']) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$list = new LearnpathList(
|
||||
api_get_user_id(),
|
||||
api_get_course_info($item['code']),
|
||||
$session_id,
|
||||
'lp.publicatedOn DESC'
|
||||
);
|
||||
$flat_list = $list->get_flat_list();
|
||||
$lps[$item['code']] = $flat_list;
|
||||
$item['title'] = Display::url(
|
||||
$item['title'],
|
||||
api_get_path(WEB_COURSE_PATH).$item['directory'].'/?id_session='.$session_id,
|
||||
['target' => SESSION_LINK_TARGET]
|
||||
);
|
||||
|
||||
foreach ($flat_list as $lp_id => $lp_item) {
|
||||
$temp[$count]['id'] = $lp_id;
|
||||
$lp_url = api_get_path(WEB_CODE_PATH).'lp/lp_controller.php?cidReq='.$item['code'].'&id_session='.$session_id.'&lp_id='.$lp_id.'&action=view';
|
||||
|
||||
$last_date = Tracking::get_last_connection_date_on_the_course(
|
||||
api_get_user_id(),
|
||||
$item,
|
||||
$session_id,
|
||||
false
|
||||
);
|
||||
|
||||
if (empty($lp_item['modified_on'])) {
|
||||
$lp_date = api_get_local_time($lp_item['created_on']);
|
||||
$image = 'new.gif';
|
||||
$label = get_lang('LearnpathAdded');
|
||||
} else {
|
||||
$lp_date = api_get_local_time($lp_item['modified_on']);
|
||||
$image = 'moderator_star.png';
|
||||
$label = get_lang('LearnpathUpdated');
|
||||
}
|
||||
|
||||
if (strtotime($last_date) < strtotime($lp_date)) {
|
||||
$icons = Display::return_icon($image, get_lang('TitleNotification').': '.$label.' - '.$lp_date);
|
||||
}
|
||||
|
||||
if (!empty($lp_item['publicated_on'])) {
|
||||
$date = substr($lp_item['publicated_on'], 0, 10);
|
||||
} else {
|
||||
$date = '-';
|
||||
}
|
||||
|
||||
// Checking LP publicated and expired_on dates
|
||||
if (!empty($lp_item['publicated_on'])) {
|
||||
$week_data = date('Y', api_strtotime($lp_item['publicated_on'], 'UTC')).' - '.get_week_from_day($lp_item['publicated_on']);
|
||||
if ($now < api_strtotime($lp_item['publicated_on'], 'UTC')) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
$week_data = '';
|
||||
}
|
||||
|
||||
if (!empty($lp_item['expired_on'])) {
|
||||
if ($now > api_strtotime($lp_item['expired_on'], 'UTC')) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$temp[$count]['cell'] = [
|
||||
$week_data,
|
||||
$date,
|
||||
$item['title'],
|
||||
Display::url($icons.' '.$lp_item['lp_name'], $lp_url, ['target' => SESSION_LINK_TARGET]),
|
||||
];
|
||||
$temp[$count]['course'] = strip_tags($item['title']);
|
||||
$temp[$count]['lp'] = $lp_item['lp_name'];
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($sidx)) {
|
||||
$temp = msort($temp, $sidx, $sord);
|
||||
}
|
||||
|
||||
$response = new stdClass();
|
||||
$i = 0;
|
||||
foreach ($temp as $key => $row) {
|
||||
$row = $row['cell'];
|
||||
if (!empty($row)) {
|
||||
if ($key >= $start && $key < ($start + $limit)) {
|
||||
$response->rows[$i]['id'] = $key;
|
||||
$response->rows[$i]['cell'] = [$row[0], $row[1], $row[2], $row[3]];
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
$total_pages = 0;
|
||||
if ($count > 0 && $limit > 0) {
|
||||
$total_pages = ceil($count / $limit);
|
||||
}
|
||||
$response->total = $total_pages;
|
||||
if ($page > $total_pages) {
|
||||
$response->page = $total_pages;
|
||||
} else {
|
||||
$response->page = $page;
|
||||
}
|
||||
$response->records = $count;
|
||||
echo json_encode($response);
|
||||
break;
|
||||
case 'session_courses_lp_by_course':
|
||||
require_once __DIR__.'/../global.inc.php';
|
||||
$now = time();
|
||||
$page = (int) $_REQUEST['page']; //page
|
||||
$limit = (int) $_REQUEST['rows']; // quantity of rows
|
||||
$sidx = isset($_REQUEST['sidx']) && !empty($_REQUEST['sidx']) ? $_REQUEST['sidx'] : 'id';
|
||||
$sidx = str_replace(['course asc,', ' '], '', $sidx);
|
||||
|
||||
$sord = $_REQUEST['sord']; //asc or desc
|
||||
if (!in_array($sord, ['asc', 'desc'])) {
|
||||
$sord = 'desc';
|
||||
}
|
||||
$session_id = (int) $_REQUEST['session_id'];
|
||||
$course_id = (int) $_REQUEST['course_id'];
|
||||
|
||||
//Filter users that does not belong to the session
|
||||
if (!api_is_platform_admin()) {
|
||||
$new_session_list = UserManager::get_personal_session_course_list(api_get_user_id());
|
||||
$my_session_list = [];
|
||||
foreach ($new_session_list as $item) {
|
||||
if (!empty($item['session_id'])) {
|
||||
$my_session_list[] = $item['session_id'];
|
||||
}
|
||||
}
|
||||
if (!in_array($session_id, $my_session_list)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$start = $limit * $page - $limit;
|
||||
$course_list = SessionManager::get_course_list_by_session_id($session_id);
|
||||
$count = 0;
|
||||
$temp = [];
|
||||
|
||||
foreach ($course_list as $item) {
|
||||
if (isset($course_id) && !empty($course_id)) {
|
||||
if ($course_id != $item['id']) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$list = new LearnpathList(
|
||||
api_get_user_id(),
|
||||
api_get_course_info($item['code']),
|
||||
$session_id
|
||||
);
|
||||
$flat_list = $list->get_flat_list();
|
||||
$lps[$item['code']] = $flat_list;
|
||||
$item['title'] = Display::url(
|
||||
$item['title'],
|
||||
api_get_path(WEB_COURSE_PATH).$item['directory'].'/?id_session='.$session_id,
|
||||
['target' => SESSION_LINK_TARGET]
|
||||
);
|
||||
foreach ($flat_list as $lp_id => $lp_item) {
|
||||
$isAllowedToEdit = api_is_allowed_to_edit(null, true);
|
||||
|
||||
if (!$isAllowedToEdit && 0 == $lp_item['lp_visibility']) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$temp[$count]['id'] = $lp_id;
|
||||
$lp_url = api_get_path(WEB_CODE_PATH).'lp/lp_controller.php?cidReq='.$item['code'].'&id_session='.$session_id.'&lp_id='.$lp_id.'&action=view';
|
||||
$last_date = Tracking::get_last_connection_date_on_the_course(
|
||||
api_get_user_id(),
|
||||
$item,
|
||||
$session_id,
|
||||
false
|
||||
);
|
||||
if (empty($lp_item['modified_on'])) {
|
||||
$lp_date = api_get_local_time($lp_item['created_on']);
|
||||
$image = 'new.gif';
|
||||
$label = get_lang('LearnpathAdded');
|
||||
} else {
|
||||
$lp_date = api_get_local_time($lp_item['modified_on']);
|
||||
$image = 'moderator_star.png';
|
||||
$label = get_lang('LearnpathUpdated');
|
||||
}
|
||||
$icons = '';
|
||||
if (strtotime($last_date) < strtotime($lp_date)) {
|
||||
$icons = Display::return_icon($image, get_lang('TitleNotification').': '.$label.' - '.$lp_date);
|
||||
}
|
||||
if (!empty($lp_item['publicated_on'])) {
|
||||
$date = substr($lp_item['publicated_on'], 0, 10);
|
||||
} else {
|
||||
$date = '-';
|
||||
}
|
||||
|
||||
// Checking LP publicated and expired_on dates
|
||||
if (!empty($lp_item['publicated_on'])) {
|
||||
if ($now < api_strtotime($lp_item['publicated_on'], 'UTC')) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!empty($lp_item['expired_on'])) {
|
||||
if ($now > api_strtotime($lp_item['expired_on'], 'UTC')) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
$temp[$count]['cell'] = [
|
||||
$date,
|
||||
$item['title'],
|
||||
Display::url($icons.' '.$lp_item['lp_name'], $lp_url, ['target' => SESSION_LINK_TARGET]),
|
||||
];
|
||||
$temp[$count]['course'] = strip_tags($item['title']);
|
||||
$temp[$count]['lp'] = $lp_item['lp_name'];
|
||||
$temp[$count]['date'] = $lp_item['publicated_on'];
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
|
||||
$temp = msort($temp, $sidx, $sord);
|
||||
$response = new stdClass();
|
||||
$i = 0;
|
||||
foreach ($temp as $key => $row) {
|
||||
$row = $row['cell'];
|
||||
if (!empty($row)) {
|
||||
if ($key >= $start && $key < ($start + $limit)) {
|
||||
$response->rows[$i]['id'] = $key;
|
||||
$response->rows[$i]['cell'] = [$row[0], $row[1], $row[2]];
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
$total_pages = 0;
|
||||
if ($count > 0 && $limit > 0) {
|
||||
$total_pages = ceil($count / $limit);
|
||||
}
|
||||
$response->total = $total_pages;
|
||||
$response->page = $page;
|
||||
if ($page > $total_pages) {
|
||||
$response->page = $total_pages;
|
||||
}
|
||||
$response->records = $count;
|
||||
|
||||
echo json_encode($response);
|
||||
break;
|
||||
case 'get_notification':
|
||||
$courseId = isset($_REQUEST['course_id']) ? (int) $_REQUEST['course_id'] : 0;
|
||||
$sessionId = isset($_REQUEST['session_id']) ? (int) $_REQUEST['session_id'] : 0;
|
||||
$status = isset($_REQUEST['status']) ? (int) $_REQUEST['status'] : 0;
|
||||
if (empty($courseId)) {
|
||||
break;
|
||||
}
|
||||
require_once __DIR__.'/../global.inc.php';
|
||||
|
||||
$courseInfo = api_get_course_info_by_id($courseId);
|
||||
$courseInfo['id_session'] = $sessionId;
|
||||
$courseInfo['status'] = $status;
|
||||
$id = 'notification_'.$courseId.'_'.$sessionId.'_'.$status;
|
||||
|
||||
$notificationId = Session::read($id);
|
||||
if ($notificationId) {
|
||||
echo Display::show_notification($courseInfo, false);
|
||||
Session::erase($notificationId);
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
echo '';
|
||||
}
|
||||
exit;
|
||||
27
main/inc/ajax/course_log.ajax.php
Normal file
27
main/inc/ajax/course_log.ajax.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request as HttpRequest;
|
||||
use Symfony\Component\HttpFoundation\Response as HttpResponse;
|
||||
|
||||
require_once __DIR__.'/../global.inc.php';
|
||||
|
||||
$httpRequest = HttpRequest::createFromGlobals();
|
||||
|
||||
$action = $httpRequest->query->has('a') ? $httpRequest->query->get('a') : $httpRequest->request->get('a');
|
||||
|
||||
TrackingCourseLog::protectIfNotAllowed();
|
||||
|
||||
$courseInfo = api_get_course_info();
|
||||
$sessionId = api_get_session_id();
|
||||
|
||||
$httpResponse = HttpResponse::create();
|
||||
|
||||
if ($action == 'graph') {
|
||||
$content = TrackingCourseLog::returnCourseGraphicalReport($courseInfo, $sessionId);
|
||||
|
||||
$httpResponse->setContent($content);
|
||||
}
|
||||
|
||||
$httpResponse->send();
|
||||
302
main/inc/ajax/document.ajax.php
Normal file
302
main/inc/ajax/document.ajax.php
Normal file
@@ -0,0 +1,302 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Responses to AJAX calls for the document upload.
|
||||
*/
|
||||
|
||||
use Chamilo\CoreBundle\Component\Editor\Driver\Driver;
|
||||
|
||||
require_once __DIR__.'/../global.inc.php';
|
||||
|
||||
$action = $_REQUEST['a'];
|
||||
switch ($action) {
|
||||
case 'get_dir_size':
|
||||
api_protect_course_script(true);
|
||||
$path = $_GET['path'] ?? '';
|
||||
$isAllowedToEdit = api_is_allowed_to_edit();
|
||||
$size = DocumentManager::getTotalFolderSize($path, $isAllowedToEdit);
|
||||
echo format_file_size($size);
|
||||
break;
|
||||
case 'get_dirs_size':
|
||||
api_protect_course_script(true);
|
||||
$requests = $_GET['requests'] ?? '';
|
||||
$isAllowedToEdit = api_is_allowed_to_edit();
|
||||
$response = [];
|
||||
$requests = explode(',', $requests);
|
||||
foreach ($requests as $request) {
|
||||
$fileSize = DocumentManager::getTotalFolderSize($request, $isAllowedToEdit);
|
||||
$data = [
|
||||
'id' => $request,
|
||||
'size' => format_file_size($fileSize),
|
||||
];
|
||||
$response[] = $data;
|
||||
}
|
||||
echo json_encode($response);
|
||||
break;
|
||||
case 'get_document_quota':
|
||||
// Getting the course quota
|
||||
$courseQuota = DocumentManager::get_course_quota();
|
||||
|
||||
// Calculating the total space
|
||||
$total = DocumentManager::documents_total_space(api_get_course_int_id());
|
||||
|
||||
// Displaying the quota
|
||||
echo DocumentManager::displaySimpleQuota($courseQuota, $total);
|
||||
break;
|
||||
case 'upload_file':
|
||||
api_protect_course_script(true);
|
||||
|
||||
if (isset($_REQUEST['chunkAction']) && 'send' === $_REQUEST['chunkAction']) {
|
||||
// It uploads the files in chunks
|
||||
if (!empty($_FILES)) {
|
||||
$tempDirectory = api_get_path(SYS_ARCHIVE_PATH);
|
||||
$files = $_FILES['files'];
|
||||
$fileList = [];
|
||||
foreach ($files as $name => $array) {
|
||||
$counter = 0;
|
||||
foreach ($array as $data) {
|
||||
$fileList[$counter][$name] = $data;
|
||||
$counter++;
|
||||
}
|
||||
}
|
||||
if (!empty($fileList)) {
|
||||
foreach ($fileList as $n => $file) {
|
||||
$tmpFile = disable_dangerous_file(
|
||||
api_replace_dangerous_char($file['name'])
|
||||
);
|
||||
|
||||
file_put_contents(
|
||||
$tempDirectory.$tmpFile,
|
||||
fopen($file['tmp_name'], 'r'),
|
||||
FILE_APPEND
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
echo json_encode([
|
||||
'files' => $_FILES,
|
||||
'errorStatus' => 0,
|
||||
]);
|
||||
exit;
|
||||
} else {
|
||||
// User access same as upload.php
|
||||
$is_allowed_to_edit = api_is_allowed_to_edit(null, true);
|
||||
|
||||
$sessionId = api_get_session_id();
|
||||
|
||||
if (!$is_allowed_to_edit && $sessionId && $_REQUEST['curdirpath'] == "/basic-course-documents__{$sessionId}__0") {
|
||||
$session = SessionManager::fetch($sessionId);
|
||||
|
||||
if (!empty($session) && $session['session_admin_id'] == api_get_user_id()) {
|
||||
$is_allowed_to_edit = true;
|
||||
}
|
||||
}
|
||||
|
||||
// This needs cleaning!
|
||||
if (api_get_group_id()) {
|
||||
$groupInfo = GroupManager::get_group_properties(api_get_group_id());
|
||||
// Only course admin or group members allowed
|
||||
if ($is_allowed_to_edit || GroupManager::is_user_in_group(api_get_user_id(), $groupInfo)) {
|
||||
if (!GroupManager::allowUploadEditDocument(
|
||||
api_get_user_id(),
|
||||
api_get_course_int_id(),
|
||||
$groupInfo
|
||||
)) {
|
||||
exit;
|
||||
}
|
||||
} else {
|
||||
exit;
|
||||
}
|
||||
} elseif ($is_allowed_to_edit ||
|
||||
DocumentManager::is_my_shared_folder(api_get_user_id(), $_REQUEST['curdirpath'], api_get_session_id())
|
||||
) {
|
||||
// ??
|
||||
} else {
|
||||
// No course admin and no group member...
|
||||
exit;
|
||||
}
|
||||
|
||||
$directoryParentId = isset($_POST['directory_parent_id']) ? (int) $_POST['directory_parent_id'] : 0;
|
||||
$currentDirectory = '';
|
||||
if (empty($directoryParentId)) {
|
||||
$currentDirectory = $_REQUEST['curdirpath'] ?? '';
|
||||
} else {
|
||||
$documentData = DocumentManager::get_document_data_by_id($directoryParentId, api_get_course_id());
|
||||
if ($documentData) {
|
||||
$currentDirectory = $documentData['path'];
|
||||
}
|
||||
}
|
||||
if (empty($currentDirectory)) {
|
||||
$currentDirectory = DIRECTORY_SEPARATOR;
|
||||
}
|
||||
$ifExists = $_POST['if_exists'] ?? '';
|
||||
$unzip = isset($_POST['unzip']) ? 1 : 0;
|
||||
|
||||
if (empty($ifExists)) {
|
||||
$fileExistsOption = api_get_setting('document_if_file_exists_option');
|
||||
$defaultFileExistsOption = 'rename';
|
||||
if (!empty($fileExistsOption)) {
|
||||
$defaultFileExistsOption = $fileExistsOption;
|
||||
}
|
||||
} else {
|
||||
$defaultFileExistsOption = $ifExists;
|
||||
}
|
||||
|
||||
if (!empty($_FILES)) {
|
||||
$files = $_FILES['files'];
|
||||
|
||||
$fileList = [];
|
||||
foreach ($files as $name => $array) {
|
||||
$counter = 0;
|
||||
foreach ($array as $data) {
|
||||
$fileList[$counter][$name] = $data;
|
||||
$counter++;
|
||||
}
|
||||
}
|
||||
|
||||
$resultList = [];
|
||||
foreach ($fileList as $fileInfo) {
|
||||
$file = processChunkedFile($fileInfo);
|
||||
|
||||
$globalFile = [];
|
||||
$globalFile['files'] = $file;
|
||||
$result = DocumentManager::upload_document(
|
||||
$globalFile,
|
||||
$currentDirectory,
|
||||
'',
|
||||
'', // comment
|
||||
$unzip,
|
||||
$defaultFileExistsOption,
|
||||
false,
|
||||
false,
|
||||
'files'
|
||||
);
|
||||
|
||||
$json = [];
|
||||
if (!empty($result) && is_array($result)) {
|
||||
$json['name'] = api_htmlentities($result['title']);
|
||||
$json['link'] = Display::url(
|
||||
api_htmlentities($result['title']),
|
||||
api_htmlentities($result['url']),
|
||||
['target' => '_blank']
|
||||
);
|
||||
$json['url'] = $result['url'];
|
||||
$json['size'] = format_file_size($file['size']);
|
||||
$json['type'] = api_htmlentities($file['type']);
|
||||
$json['result'] = Display::return_icon(
|
||||
'accept.png',
|
||||
get_lang('Uploaded')
|
||||
);
|
||||
} else {
|
||||
$json['name'] = $file['name'] ?? get_lang('Unknown');
|
||||
$json['url'] = '';
|
||||
$json['error'] = get_lang('Error');
|
||||
}
|
||||
$resultList[] = $json;
|
||||
}
|
||||
|
||||
echo json_encode(['files' => $resultList]);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'ck_uploadimage':
|
||||
if (true !== api_get_configuration_value('enable_uploadimage_editor')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
api_protect_course_script(true);
|
||||
|
||||
// it comes from uploaimage drag and drop ckeditor
|
||||
$isCkUploadImage = ($_COOKIE['ckCsrfToken'] == $_POST['ckCsrfToken']);
|
||||
|
||||
if (!$isCkUploadImage) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$data = [];
|
||||
$fileUpload = $_FILES['upload'];
|
||||
$mimeType = mime_content_type($fileUpload['tmp_name']);
|
||||
|
||||
$isMimeAccepted = (new Driver())->mimeAccepted($mimeType, ['image']);
|
||||
|
||||
if (!$isMimeAccepted) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$isAllowedToEdit = api_is_allowed_to_edit(null, true);
|
||||
if ($isAllowedToEdit) {
|
||||
$globalFile = ['files' => $fileUpload];
|
||||
$result = DocumentManager::upload_document(
|
||||
$globalFile,
|
||||
'/',
|
||||
'',
|
||||
'',
|
||||
0,
|
||||
'rename',
|
||||
false,
|
||||
false,
|
||||
'files'
|
||||
);
|
||||
|
||||
if (!$result) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$relativeUrl = str_replace(api_get_path(WEB_PATH), '/', $result['direct_url']);
|
||||
$data = [
|
||||
'uploaded' => 1,
|
||||
'fileName' => $fileUpload['name'],
|
||||
'url' => $relativeUrl,
|
||||
];
|
||||
} else {
|
||||
$userId = api_get_user_id();
|
||||
$syspath = UserManager::getUserPathById($userId, 'system').'my_files';
|
||||
if (!is_dir($syspath)) {
|
||||
mkdir($syspath, api_get_permissions_for_new_directories(), true);
|
||||
}
|
||||
$webpath = UserManager::getUserPathById($userId, 'web').'my_files';
|
||||
$fileUploadName = $fileUpload['name'];
|
||||
if (file_exists($syspath.$fileUploadName)) {
|
||||
$extension = pathinfo($fileUploadName, PATHINFO_EXTENSION);
|
||||
$fileName = pathinfo($fileUploadName, PATHINFO_FILENAME);
|
||||
$suffix = '_'.uniqid();
|
||||
$fileUploadName = $fileName.$suffix.'.'.$extension;
|
||||
}
|
||||
|
||||
$personalDriver = new PersonalDriver();
|
||||
$uploadResult = $personalDriver->mimeAccepted(mime_content_type($fileUpload['tmp_name']), ['image']);
|
||||
|
||||
if (!$uploadResult || !move_uploaded_file($fileUpload['tmp_name'], $syspath.$fileUploadName)) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$url = $webpath.$fileUploadName;
|
||||
$relativeUrl = str_replace(api_get_path(WEB_PATH), '/', $url);
|
||||
$data = [
|
||||
'uploaded' => 1,
|
||||
'fileName' => $fileUploadName,
|
||||
'url' => $relativeUrl,
|
||||
];
|
||||
}
|
||||
echo json_encode($data);
|
||||
exit;
|
||||
case 'document_preview':
|
||||
$courseInfo = api_get_course_info_by_id($_REQUEST['course_id']);
|
||||
if (!empty($courseInfo) && is_array($courseInfo)) {
|
||||
echo DocumentManager::get_document_preview(
|
||||
$courseInfo,
|
||||
false,
|
||||
'_blank',
|
||||
$_REQUEST['session_id']
|
||||
);
|
||||
}
|
||||
break;
|
||||
case 'document_destination':
|
||||
//obtained the bootstrap-select selected value via ajax
|
||||
$dirValue = $_POST['dirValue'] ?? null;
|
||||
echo Security::remove_XSS($dirValue);
|
||||
break;
|
||||
}
|
||||
exit;
|
||||
120
main/inc/ajax/dropbox.ajax.php
Normal file
120
main/inc/ajax/dropbox.ajax.php
Normal file
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Responses to AJAX calls for the document upload.
|
||||
*/
|
||||
require_once __DIR__.'/../global.inc.php';
|
||||
require_once api_get_path(SYS_CODE_PATH).'dropbox/dropbox_functions.inc.php';
|
||||
|
||||
$action = $_REQUEST['a'];
|
||||
switch ($action) {
|
||||
case 'upload_file':
|
||||
api_protect_course_script(true);
|
||||
|
||||
if (isset($_REQUEST['chunkAction']) && 'send' === $_REQUEST['chunkAction']) {
|
||||
// It uploads the files in chunks
|
||||
if (!empty($_FILES)) {
|
||||
$tempDirectory = api_get_path(SYS_ARCHIVE_PATH);
|
||||
$files = $_FILES['files'];
|
||||
$fileList = [];
|
||||
foreach ($files as $name => $array) {
|
||||
$counter = 0;
|
||||
foreach ($array as $data) {
|
||||
$fileList[$counter][$name] = $data;
|
||||
$counter++;
|
||||
}
|
||||
}
|
||||
if (!empty($fileList)) {
|
||||
foreach ($fileList as $n => $file) {
|
||||
$tmpFile = disable_dangerous_file(
|
||||
api_replace_dangerous_char($file['name'])
|
||||
);
|
||||
|
||||
file_put_contents(
|
||||
$tempDirectory.$tmpFile,
|
||||
fopen($file['tmp_name'], 'r'),
|
||||
FILE_APPEND
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
echo json_encode([
|
||||
'files' => $_FILES,
|
||||
'errorStatus' => 0,
|
||||
]);
|
||||
exit;
|
||||
} else {
|
||||
|
||||
// User access same as upload.php
|
||||
$is_allowed_to_edit = api_is_allowed_to_edit(null, true);
|
||||
|
||||
$recipients = isset($_POST['recipients']) ? $_POST['recipients'] : '';
|
||||
$id = isset($_GET['id']) ? (int) $_GET['id'] : 0;
|
||||
|
||||
if (empty($recipients) && empty($id)) {
|
||||
$resultList[] = ['error' => get_lang('YouMustSelectAtLeastOneDestinee')];
|
||||
echo json_encode(['files' => $resultList]);
|
||||
exit;
|
||||
}
|
||||
$work = null;
|
||||
if (!empty($id)) {
|
||||
$work = new Dropbox_SentWork($id);
|
||||
if (empty($work)) {
|
||||
$resultList[] = ['error' => get_lang('Error')];
|
||||
echo json_encode(['files' => $resultList]);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($_FILES)) {
|
||||
$files = $_FILES['files'];
|
||||
$fileList = [];
|
||||
foreach ($files as $name => $array) {
|
||||
$counter = 0;
|
||||
foreach ($array as $data) {
|
||||
$fileList[$counter][$name] = $data;
|
||||
$counter++;
|
||||
}
|
||||
}
|
||||
|
||||
$resultList = [];
|
||||
foreach ($fileList as $fileInfo) {
|
||||
$file = processChunkedFile($fileInfo);
|
||||
|
||||
$globalFile = [];
|
||||
$globalFile['files'] = $file;
|
||||
/** @var Dropbox_SentWork $result */
|
||||
$result = store_add_dropbox($file, $work);
|
||||
|
||||
$json = [];
|
||||
if (!empty($result)) {
|
||||
$json['name'] = Display::url(
|
||||
api_htmlentities($result->title),
|
||||
api_htmlentities(api_get_path(WEB_CODE_PATH).'dropbox/index.php?'.api_get_cidreq()),
|
||||
['target' => '_blank']
|
||||
);
|
||||
|
||||
$json['url'] = api_get_path(WEB_CODE_PATH).'dropbox/index.php?'.api_get_cidreq();
|
||||
$json['size'] = format_file_size($result->filesize);
|
||||
$json['type'] = api_htmlentities($file['type']);
|
||||
$json['result'] = Display::return_icon(
|
||||
'accept.png',
|
||||
get_lang('Uploaded')
|
||||
);
|
||||
} else {
|
||||
$json['result'] = Display::return_icon(
|
||||
'exclamation.png',
|
||||
get_lang('Error')
|
||||
);
|
||||
}
|
||||
$resultList[] = $json;
|
||||
}
|
||||
|
||||
echo json_encode(['files' => $resultList]);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
exit;
|
||||
25
main/inc/ajax/events.ajax.php
Normal file
25
main/inc/ajax/events.ajax.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
require_once __DIR__.'/../global.inc.php';
|
||||
|
||||
$id = isset($_REQUEST['id']) ? $_REQUEST['id'] : null;
|
||||
$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : null;
|
||||
$event_name = isset($_REQUEST['eventName']) ? $_REQUEST['eventName'] : null;
|
||||
|
||||
api_protect_admin_script();
|
||||
|
||||
switch ($action) {
|
||||
case 'getEventTypes':
|
||||
$events = Event::get_all_event_types();
|
||||
echo json_encode($events);
|
||||
break;
|
||||
case 'getUsers':
|
||||
$users = UserManager::get_user_list();
|
||||
echo json_encode($users);
|
||||
break;
|
||||
case 'get_event_users':
|
||||
$users = Event::get_event_users($event_name);
|
||||
echo json_encode($users);
|
||||
break;
|
||||
}
|
||||
exit;
|
||||
1270
main/inc/ajax/exercise.ajax.php
Normal file
1270
main/inc/ajax/exercise.ajax.php
Normal file
File diff suppressed because it is too large
Load Diff
185
main/inc/ajax/extra_field.ajax.php
Normal file
185
main/inc/ajax/extra_field.ajax.php
Normal file
@@ -0,0 +1,185 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use Chamilo\CoreBundle\Entity\Tag;
|
||||
|
||||
require_once __DIR__.'/../global.inc.php';
|
||||
|
||||
$action = isset($_GET['a']) ? $_GET['a'] : '';
|
||||
$type = isset($_REQUEST['type']) ? $_REQUEST['type'] : null;
|
||||
$fieldId = isset($_REQUEST['field_id']) ? $_REQUEST['field_id'] : null;
|
||||
|
||||
switch ($action) {
|
||||
case 'delete_file':
|
||||
api_protect_admin_script();
|
||||
|
||||
$itemId = isset($_REQUEST['item_id']) ? $_REQUEST['item_id'] : null;
|
||||
$extraFieldValue = new ExtraFieldValue($type);
|
||||
$data = $extraFieldValue->get_values_by_handler_and_field_id($itemId, $fieldId);
|
||||
if (!empty($data) && isset($data['id']) && !empty($data['value'])) {
|
||||
$extraFieldValue->deleteValuesByHandlerAndFieldAndValue($itemId, $data['field_id'], $data['value']);
|
||||
echo 1;
|
||||
break;
|
||||
}
|
||||
echo 0;
|
||||
break;
|
||||
case 'get_second_select_options':
|
||||
$option_value_id = isset($_REQUEST['option_value_id']) ? $_REQUEST['option_value_id'] : null;
|
||||
if (!empty($type) && !empty($fieldId) && !empty($option_value_id)) {
|
||||
$field_options = new ExtraFieldOption($type);
|
||||
echo $field_options->get_second_select_field_options_by_field(
|
||||
$option_value_id,
|
||||
true
|
||||
);
|
||||
}
|
||||
break;
|
||||
case 'search_tags':
|
||||
header('Content-Type: application/json');
|
||||
$tag = $_REQUEST['q'] ?? null;
|
||||
$pageLimit = isset($_REQUEST['page_limit']) ? (int) $_REQUEST['page_limit'] : 10;
|
||||
$byId = !empty($_REQUEST['byid']);
|
||||
$result = [];
|
||||
|
||||
if (empty($tag)) {
|
||||
echo json_encode(['items' => $result]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$tagRepo = Database::getManager()->getRepository(Tag::class);
|
||||
|
||||
if ('portfolio' === $type) {
|
||||
$tags = $tagRepo
|
||||
->findForPortfolioInCourseQuery(
|
||||
api_get_course_entity(),
|
||||
api_get_session_entity()
|
||||
)
|
||||
->getQuery()
|
||||
->getResult();
|
||||
} else {
|
||||
$tags = $tagRepo->findByFieldIdAndText($fieldId, $tag, $pageLimit);
|
||||
}
|
||||
|
||||
/** @var Tag $tag */
|
||||
foreach ($tags as $tag) {
|
||||
$result[] = [
|
||||
'id' => $byId ? $tag->getId() : $tag->getTag(),
|
||||
'text' => $tag->getTag(),
|
||||
];
|
||||
}
|
||||
|
||||
echo json_encode(['items' => $result]);
|
||||
break;
|
||||
case 'search_options_from_tags':
|
||||
$type = isset($_REQUEST['type']) ? $_REQUEST['type'] : null;
|
||||
$fieldId = isset($_REQUEST['field_id']) ? $_REQUEST['field_id'] : null;
|
||||
$tag = isset($_REQUEST['tag']) ? $_REQUEST['tag'] : null;
|
||||
$extraFieldOption = new ExtraFieldOption($type);
|
||||
|
||||
$from = isset($_REQUEST['from']) ? $_REQUEST['from'] : '';
|
||||
$search = isset($_REQUEST['search']) ? $_REQUEST['search'] : '';
|
||||
$options = isset($_REQUEST['options']) ? json_decode($_REQUEST['options']) : '';
|
||||
|
||||
$extraField = new ExtraField('session');
|
||||
$result = $extraField->searchOptionsFromTags($from, $search, $options);
|
||||
$options = [];
|
||||
$groups = [];
|
||||
|
||||
foreach ($result as $data) {
|
||||
// Try to get the translation
|
||||
$displayText = $data['display_text'];
|
||||
$valueToTranslate = str_replace('-', '', $data['value']);
|
||||
$valueTranslated = str_replace(['[=', '=]'], '', get_lang($valueToTranslate));
|
||||
if ($valueToTranslate != $valueTranslated) {
|
||||
$displayText = $valueTranslated;
|
||||
}
|
||||
$groups[$displayText][] = [
|
||||
'id' => $data['id'],
|
||||
'text' => $data['tag'],
|
||||
];
|
||||
}
|
||||
|
||||
foreach ($groups as $key => $data) {
|
||||
$options[] = [
|
||||
'text' => $key,
|
||||
'children' => $groups[$key],
|
||||
];
|
||||
}
|
||||
echo json_encode($options);
|
||||
break;
|
||||
case 'order':
|
||||
$variable = isset($_REQUEST['field_variable']) ? $_REQUEST['field_variable'] : '';
|
||||
$save = isset($_REQUEST['save']) ? $_REQUEST['save'] : '';
|
||||
$values = isset($_REQUEST['values']) ? json_decode($_REQUEST['values']) : '';
|
||||
$extraField = new ExtraField('session');
|
||||
$extraFieldInfo = $extraField->get_handler_field_info_by_field_variable(str_replace('extra_', '', $variable));
|
||||
|
||||
$em = Database::getManager();
|
||||
|
||||
$search = [
|
||||
'user' => api_get_user_id(),
|
||||
'field' => $extraFieldInfo['id'],
|
||||
];
|
||||
|
||||
$extraFieldSavedSearch = $em->getRepository('ChamiloCoreBundle:ExtraFieldSavedSearch')->findOneBy($search);
|
||||
|
||||
if ($save) {
|
||||
$extraField = new \Chamilo\CoreBundle\Entity\ExtraFieldSavedSearch('session');
|
||||
if ($extraFieldSavedSearch) {
|
||||
$extraFieldSavedSearch->setValue($values);
|
||||
$em->merge($extraFieldSavedSearch);
|
||||
$em->flush();
|
||||
}
|
||||
}
|
||||
|
||||
if ($extraFieldInfo) {
|
||||
/** @var \Chamilo\CoreBundle\Entity\ExtraFieldSavedSearch $options */
|
||||
$extraFieldSavedSearch = $em->getRepository('ChamiloCoreBundle:ExtraFieldSavedSearch')->findOneBy($search);
|
||||
$values = $extraFieldSavedSearch->getValue();
|
||||
$url = api_get_self().'?a=order&save=1&field_variable='.$variable;
|
||||
|
||||
$html = '
|
||||
<script>
|
||||
$(function() {
|
||||
$( "#sortable" ).sortable();
|
||||
$( "#sortable" ).disableSelection();
|
||||
|
||||
$( "#link_'.$variable.'" ).on("click", function() {
|
||||
var newList = [];
|
||||
$("#sortable").find("li").each(function(){
|
||||
newList.push($(this).text());
|
||||
});
|
||||
|
||||
var save = JSON.stringify(newList);
|
||||
$.ajax({
|
||||
url: "'.$url.'",
|
||||
dataType: "json",
|
||||
data: "values="+save,
|
||||
success: function(data) {
|
||||
}
|
||||
});
|
||||
|
||||
alert("'.get_lang('Saved').'");
|
||||
location.reload();
|
||||
return false;
|
||||
|
||||
});
|
||||
});
|
||||
</script>';
|
||||
|
||||
$html .= '<ul id="sortable">';
|
||||
foreach ($values as $value) {
|
||||
$html .= '<li class="ui-state-default">';
|
||||
$html .= $value;
|
||||
$html .= '</li>';
|
||||
}
|
||||
$html .= '</ul>';
|
||||
$html .= Display::url(get_lang('Save'), '#', ['id' => 'link_'.$variable, 'class' => 'btn btn-primary']);
|
||||
echo $html;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
exit;
|
||||
break;
|
||||
}
|
||||
exit;
|
||||
21
main/inc/ajax/form.ajax.php
Normal file
21
main/inc/ajax/form.ajax.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
require_once __DIR__.'/../global.inc.php';
|
||||
|
||||
$action = isset($_REQUEST['a']) ? $_REQUEST['a'] : null;
|
||||
|
||||
switch ($action) {
|
||||
case 'get_captcha':
|
||||
header('Content-Type: image/jpeg');
|
||||
|
||||
$sessionVar = empty($_REQUEST['var']) ? '_HTML_QuickForm_CAPTCHA' : $_REQUEST['var'];
|
||||
if (isset($_SESSION[$sessionVar]) && !empty($_SESSION[$sessionVar])) {
|
||||
$obj = $_SESSION[$sessionVar];
|
||||
// Force a new CAPTCHA for each one displayed/** @var Text_CAPTCHA $obj */;
|
||||
$obj->generate(true);
|
||||
echo $image = $obj->getCAPTCHA();
|
||||
}
|
||||
exit;
|
||||
break;
|
||||
}
|
||||
204
main/inc/ajax/forum.ajax.php
Normal file
204
main/inc/ajax/forum.ajax.php
Normal file
@@ -0,0 +1,204 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use Chamilo\CourseBundle\Entity\CForumPost;
|
||||
|
||||
/**
|
||||
* Responses to AJAX calls for forum attachments.
|
||||
*
|
||||
* @package chamilo/forum
|
||||
*
|
||||
* @author Daniel Barreto Alva <daniel.barreto@beeznest.com>
|
||||
*/
|
||||
require_once __DIR__.'/../global.inc.php';
|
||||
require_once api_get_path(SYS_CODE_PATH).'forum/forumfunction.inc.php';
|
||||
|
||||
// First, protect this script
|
||||
api_protect_course_script(false);
|
||||
|
||||
$action = isset($_REQUEST['a']) ? $_REQUEST['a'] : null;
|
||||
// Create a default error response
|
||||
$json = [
|
||||
'error' => true,
|
||||
'errorMessage' => 'ERROR',
|
||||
];
|
||||
|
||||
// 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)
|
||||
// 2. the forum category, forum or thread is locked (locked <>0)
|
||||
// 3. if anonymous posts are not allowed
|
||||
// The only exception is the course manager
|
||||
// They are several pieces for clarity.
|
||||
if (!api_is_allowed_to_edit(null, true) &&
|
||||
(
|
||||
($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) &&
|
||||
(
|
||||
($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() && $current_forum['allow_anonymous'] == 0) {
|
||||
$json['errorMessage'] = '3. if anonymous posts are not allowed';
|
||||
break;
|
||||
}
|
||||
// If pass all previous control, user can edit post
|
||||
$courseId = isset($_REQUEST['c_id']) ? intval($_REQUEST['c_id']) : api_get_course_int_id();
|
||||
$json['courseId'] = $courseId;
|
||||
$forumId = isset($_REQUEST['forum']) ? intval($_REQUEST['forum']) : null;
|
||||
$json['forum'] = $forumId;
|
||||
$threadId = isset($_REQUEST['thread']) ? intval($_REQUEST['thread']) : null;
|
||||
$json['thread'] = $threadId;
|
||||
$postId = isset($_REQUEST['postId']) ? intval($_REQUEST['postId']) : null;
|
||||
$json['postId'] = $postId;
|
||||
|
||||
if (!empty($courseId) &&
|
||||
!is_null($forumId) &&
|
||||
!is_null($threadId) &&
|
||||
!is_null($postId)
|
||||
) {
|
||||
// Save forum attachment
|
||||
$attachId = add_forum_attachment_file('', $postId);
|
||||
if ($attachId !== false) {
|
||||
// Get prepared array of attachment data
|
||||
$array = getAttachedFiles(
|
||||
$forumId,
|
||||
$threadId,
|
||||
$postId,
|
||||
$attachId,
|
||||
$courseId
|
||||
);
|
||||
// Check if array data is consistent
|
||||
if (isset($array['name'])) {
|
||||
$json['error'] = false;
|
||||
$json['errorMessage'] = 'Success';
|
||||
$json = array_merge($json, $array);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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);
|
||||
// The user is not allowed here if
|
||||
// 1. the forum category, forum or thread is invisible (visibility==0)
|
||||
// 2. the forum category, forum or thread is locked (locked <>0)
|
||||
// 3. if anonymous posts are not allowed
|
||||
// 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) &&
|
||||
(
|
||||
($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) &&
|
||||
(
|
||||
($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() && $current_forum['allow_anonymous'] == 0) {
|
||||
$json['errorMessage'] = '3. if anonymous posts are not allowed';
|
||||
break;
|
||||
}
|
||||
$group_id = api_get_group_id();
|
||||
$groupInfo = GroupManager::get_group_properties($group_id);
|
||||
if (!api_is_allowed_to_edit(null, true) &&
|
||||
$current_forum['allow_edit'] == 0 &&
|
||||
($group_id && !GroupManager::is_tutor_of_group(api_get_user_id(), $groupInfo))
|
||||
) {
|
||||
$json['errorMessage'] = '4. if editing of replies is not allowed';
|
||||
break;
|
||||
}
|
||||
// If pass all previous control, user can edit post
|
||||
$attachId = $_REQUEST['attachId'];
|
||||
$threadId = $_REQUEST['thread'];
|
||||
// Delete forum attachment from database and file system
|
||||
$affectedRows = delete_attachment(0, $attachId, false);
|
||||
if ($affectedRows > 0) {
|
||||
$json['error'] = false;
|
||||
$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;
|
||||
}
|
||||
}
|
||||
exit;
|
||||
100
main/inc/ajax/gradebook.ajax.php
Normal file
100
main/inc/ajax/gradebook.ajax.php
Normal file
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Responses to AJAX calls.
|
||||
*/
|
||||
require_once __DIR__.'/../global.inc.php';
|
||||
|
||||
api_protect_course_script(true);
|
||||
|
||||
$action = $_REQUEST['a'];
|
||||
|
||||
switch ($action) {
|
||||
case 'add_gradebook_comment':
|
||||
if (true !== api_get_configuration_value('allow_gradebook_comments')) {
|
||||
exit;
|
||||
}
|
||||
if (api_is_allowed_to_edit(null, true)) {
|
||||
$userId = $_REQUEST['user_id'] ?? 0;
|
||||
$gradeBookId = $_REQUEST['gradebook_id'] ?? 0;
|
||||
$comment = $_REQUEST['comment'] ?? '';
|
||||
GradebookUtils::saveComment($gradeBookId, $userId, $comment);
|
||||
echo 1;
|
||||
exit;
|
||||
}
|
||||
echo 0;
|
||||
break;
|
||||
case 'get_gradebook_weight':
|
||||
if (api_is_allowed_to_edit(null, true)) {
|
||||
$cat_id = $_GET['cat_id'];
|
||||
$cat = Category::load($cat_id);
|
||||
if ($cat && isset($cat[0])) {
|
||||
echo $cat[0]->get_weight();
|
||||
} else {
|
||||
echo 0;
|
||||
}
|
||||
}
|
||||
break; /*
|
||||
case 'generate_custom_report':
|
||||
if (api_is_allowed_to_edit(null, true)) {
|
||||
$allow = api_get_configuration_value('gradebook_custom_student_report');
|
||||
if (!$allow) {
|
||||
exit;
|
||||
}
|
||||
$form = new FormValidator(
|
||||
'search',
|
||||
'get',
|
||||
api_get_path(WEB_CODE_PATH).'gradebook/index.php?'.api_get_cidreq().'&action=generate_custom_report'
|
||||
);
|
||||
$form->addText('custom_course_id', get_lang('CourseId'));
|
||||
$form->addDateRangePicker('range', get_lang('DateRange'));
|
||||
$form->addHidden('action', 'generate_custom_report');
|
||||
$form->addButtonSearch();
|
||||
$form->display();
|
||||
}
|
||||
break;*/
|
||||
case 'export_all_certificates':
|
||||
$categoryId = (int) $_GET['cat_id'];
|
||||
$filterOfficialCodeGet = isset($_GET['filter']) ? Security::remove_XSS($_GET['filter']) : null;
|
||||
|
||||
if (api_is_student_boss()) {
|
||||
$userGroup = new UserGroup();
|
||||
$userList = $userGroup->getGroupUsersByUser(api_get_user_id());
|
||||
} else {
|
||||
$userList = [];
|
||||
if (!empty($filterOfficialCodeGet)) {
|
||||
$userList = UserManager::getUsersByOfficialCode($filterOfficialCodeGet);
|
||||
}
|
||||
}
|
||||
|
||||
$courseCode = api_get_course_id();
|
||||
$sessionId = api_get_session_id();
|
||||
|
||||
$commandScript = api_get_path(SYS_CODE_PATH).'gradebook/cli/export_all_certificates.php';
|
||||
|
||||
$userList = implode(',', $userList);
|
||||
|
||||
shell_exec("php $commandScript $courseCode $sessionId $categoryId $userList > /dev/null &");
|
||||
break;
|
||||
case 'verify_export_all_certificates':
|
||||
$categoryId = (int) $_GET['cat_id'];
|
||||
$courseCode = isset($_GET['cidReq']) ? Security::remove_XSS($_GET['cidReq']) : api_get_course_id();
|
||||
$sessionId = isset($_GET['id_session']) ? (int) $_GET['id_session'] : api_get_session_id();
|
||||
$date = api_get_utc_datetime(null, false, true);
|
||||
|
||||
$pdfName = 'certs_'.$courseCode.'_'.$sessionId.'_'.$categoryId.'_'.$date->format('Y-m-d');
|
||||
|
||||
$sysFinalFile = api_get_path(SYS_ARCHIVE_PATH)."$pdfName.pdf";
|
||||
$webFinalFile = api_get_path(WEB_ARCHIVE_PATH)."$pdfName.pdf";
|
||||
|
||||
if (file_exists($sysFinalFile)) {
|
||||
echo $webFinalFile;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
echo '';
|
||||
break;
|
||||
}
|
||||
exit;
|
||||
27
main/inc/ajax/group.ajax.php
Normal file
27
main/inc/ajax/group.ajax.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
require_once __DIR__.'/../global.inc.php';
|
||||
|
||||
$action = isset($_REQUEST['a']) ? $_REQUEST['a'] : '';
|
||||
$isAllowedToEdit = api_is_allowed_to_edit();
|
||||
|
||||
switch ($action) {
|
||||
case 'search':
|
||||
if ($isAllowedToEdit) {
|
||||
$groups = GroupManager::getGroupListFilterByName($_REQUEST['q'], null, api_get_course_int_id());
|
||||
$list = [];
|
||||
foreach ($groups as $group) {
|
||||
$list[] = [
|
||||
'id' => $group['iid'],
|
||||
'text' => $group['name'],
|
||||
];
|
||||
}
|
||||
echo json_encode(['items' => $list]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
exit;
|
||||
6
main/inc/ajax/index.html
Normal file
6
main/inc/ajax/index.html
Normal file
@@ -0,0 +1,6 @@
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
86
main/inc/ajax/install.ajax.php
Normal file
86
main/inc/ajax/install.ajax.php
Normal file
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
|
||||
/**
|
||||
* Responses to AJAX calls for install.
|
||||
*/
|
||||
require_once __DIR__.'/../../../vendor/autoload.php';
|
||||
|
||||
$action = $_GET['a'];
|
||||
|
||||
switch ($action) {
|
||||
case 'send_contact_information':
|
||||
if (!empty($_POST)) {
|
||||
// get params from contact form
|
||||
$person_name = $_POST['person_name'];
|
||||
$person_email = $_POST['person_email'];
|
||||
$person_role = $_POST['person_role'];
|
||||
$financial_decision = $_POST['financial_decision'];
|
||||
$contact_language = $_POST['language'];
|
||||
$company_name = $_POST['company_name'];
|
||||
$company_activity = $_POST['company_activity'];
|
||||
$company_country = $_POST['company_country'];
|
||||
$company_city = $_POST['company_city'];
|
||||
|
||||
// validating required fields
|
||||
$a_required_fields = [$person_name, $person_role, $company_name, $company_activity, $company_country];
|
||||
$required_field_error = false;
|
||||
foreach ($a_required_fields as $required_file) {
|
||||
if (trim($required_file) === '') {
|
||||
$required_field_error = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Return error if any of the required fields is empty
|
||||
if ($required_field_error) {
|
||||
echo 'required_field_error';
|
||||
break;
|
||||
} else {
|
||||
// save contact information with web service
|
||||
// create a client
|
||||
|
||||
$url = 'https://version.chamilo.org/contactv2.php';
|
||||
$options = [
|
||||
'verify' => false,
|
||||
];
|
||||
|
||||
$urlValidated = false;
|
||||
try {
|
||||
$client = new GuzzleHttp\Client();
|
||||
$res = $client->request('GET', $url, $options);
|
||||
if ($res->getStatusCode() == '200' || $res->getStatusCode() == '301') {
|
||||
$urlValidated = true;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
error_log("Could not check $url from ".__FILE__);
|
||||
break;
|
||||
}
|
||||
|
||||
$data = [
|
||||
'person_name' => $person_name,
|
||||
'person_email' => $person_email,
|
||||
'person_role' => $person_role,
|
||||
'financial_decision' => $financial_decision,
|
||||
'contact_language' => $contact_language,
|
||||
'company_name' => $company_name,
|
||||
'company_activity' => $company_activity,
|
||||
'company_country' => $company_country,
|
||||
'company_city' => $company_city,
|
||||
];
|
||||
|
||||
$client = new GuzzleHttp\Client();
|
||||
$options['query'] = $data;
|
||||
$res = $client->request('GET', $url, $options);
|
||||
if ($res->getStatusCode() == '200') {
|
||||
echo '1';
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
echo '';
|
||||
}
|
||||
exit;
|
||||
81
main/inc/ajax/lang.ajax.php
Normal file
81
main/inc/ajax/lang.ajax.php
Normal file
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Responses to AJAX calls.
|
||||
*/
|
||||
require_once __DIR__.'/../global.inc.php';
|
||||
|
||||
api_protect_course_script(true);
|
||||
|
||||
$action = $_REQUEST['a'];
|
||||
|
||||
switch ($action) {
|
||||
case 'translate_html':
|
||||
header('Content-type: application/x-javascript');
|
||||
|
||||
echo api_get_language_translate_html();
|
||||
break;
|
||||
case 'translate_portfolio_category':
|
||||
if (false === Security::check_token('get')) {
|
||||
exit;
|
||||
}
|
||||
Security::clear_token();
|
||||
if (isset($_REQUEST['new_language']) && isset($_REQUEST['variable_language']) && isset($_REQUEST['category_id'])) {
|
||||
$newLanguage = Security::remove_XSS($_REQUEST['new_language']);
|
||||
$langVariable = ltrim(
|
||||
Security::remove_XSS($_REQUEST['variable_language']),
|
||||
'$'
|
||||
);
|
||||
$categoryId = (int) $_REQUEST['category_id'];
|
||||
$languageId = (int) $_REQUEST['id'];
|
||||
$subLanguageId = (int) $_REQUEST['sub'];
|
||||
|
||||
$langFilesToLoad = SubLanguageManager::get_lang_folder_files_list(
|
||||
api_get_path(SYS_LANG_PATH).'english',
|
||||
true
|
||||
);
|
||||
|
||||
$fileLanguage = $langFilesToLoad[0].'.inc.php';
|
||||
$allDataOfLanguage = SubLanguageManager::get_all_information_of_sub_language($languageId, $subLanguageId);
|
||||
|
||||
$pathFolder = api_get_path(SYS_LANG_PATH).$allDataOfLanguage['dokeos_folder'].'/'.$fileLanguage;
|
||||
$allFileOfDirectory = SubLanguageManager::get_all_language_variable_in_file($pathFolder);
|
||||
$returnValue = SubLanguageManager::add_file_in_language_directory($pathFolder);
|
||||
|
||||
//update variable language
|
||||
$allFileOfDirectory[$langVariable] = $newLanguage;
|
||||
|
||||
$resultArray = [];
|
||||
foreach ($allFileOfDirectory as $key => $value) {
|
||||
$resultArray[$key] = SubLanguageManager::write_data_in_file($pathFolder, $value, $key);
|
||||
}
|
||||
|
||||
$variablesWithProblems = '';
|
||||
if (!empty($resultArray)) {
|
||||
foreach ($resultArray as $key => $result) {
|
||||
if ($result == false) {
|
||||
$variablesWithProblems .= $key.' <br />';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_REQUEST['redirect'])) {
|
||||
$message = Display::return_message(get_lang('TheNewWordHasBeenAdded'), 'success');
|
||||
if (!empty($variablesWithProblems)) {
|
||||
$message = Display::return_message(
|
||||
$pathFolder.' '.get_lang('IsNotWritable').'<br /> '.api_ucwords(get_lang('ErrorsFound'))
|
||||
.': <br />'.$variablesWithProblems,
|
||||
'error'
|
||||
);
|
||||
}
|
||||
Display::addFlash($message);
|
||||
header('Location: '.api_get_path(WEB_CODE_PATH).'portfolio/index.php?'.api_get_cidreq().'&action=translate_category&id='.$categoryId.'&sub_language='.$subLanguageId);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
echo '';
|
||||
}
|
||||
exit;
|
||||
39
main/inc/ajax/link.ajax.php
Normal file
39
main/inc/ajax/link.ajax.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Responses to AJAX calls.
|
||||
*/
|
||||
require_once __DIR__.'/../global.inc.php';
|
||||
|
||||
api_protect_course_script(true);
|
||||
|
||||
$action = $_REQUEST['a'];
|
||||
|
||||
switch ($action) {
|
||||
case 'check_url':
|
||||
if (api_is_allowed_to_edit(null, true)) {
|
||||
$url = $_REQUEST['url'];
|
||||
$result = \Link::checkUrl($url);
|
||||
|
||||
if ($result) {
|
||||
echo Display::return_icon(
|
||||
'check-circle.png',
|
||||
get_lang('Ok'),
|
||||
null,
|
||||
ICON_SIZE_TINY
|
||||
);
|
||||
} else {
|
||||
echo Display::return_icon(
|
||||
'closed-circle.png',
|
||||
get_lang('Wrong'),
|
||||
null,
|
||||
ICON_SIZE_TINY
|
||||
);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
echo '';
|
||||
}
|
||||
exit;
|
||||
331
main/inc/ajax/lp.ajax.php
Normal file
331
main/inc/ajax/lp.ajax.php
Normal file
@@ -0,0 +1,331 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use ChamiloSession as Session;
|
||||
|
||||
/**
|
||||
* Responses to AJAX calls.
|
||||
*/
|
||||
require_once __DIR__.'/../global.inc.php';
|
||||
api_protect_course_script(true);
|
||||
|
||||
$debug = false;
|
||||
$action = isset($_REQUEST['a']) ? $_REQUEST['a'] : '';
|
||||
|
||||
$courseId = api_get_course_int_id();
|
||||
$sessionId = api_get_session_id();
|
||||
|
||||
if ($debug) {
|
||||
error_log('----------lp.ajax-------------- action '.$action);
|
||||
}
|
||||
|
||||
// We check if a tool provider
|
||||
if (isset($_REQUEST['lti_launch_id'])) {
|
||||
$ltiLaunchId = Security::remove_XSS($_REQUEST['lti_launch_id']);
|
||||
$_SESSION['oLP']->lti_launch_id = $ltiLaunchId;
|
||||
}
|
||||
|
||||
switch ($action) {
|
||||
case 'get_lp_list_by_course':
|
||||
$course_id = (isset($_GET['course_id']) && !empty($_GET['course_id'])) ? (int) $_GET['course_id'] : 0;
|
||||
$session_id = (isset($_GET['session_id']) && !empty($_GET['session_id'])) ? (int) $_GET['session_id'] : 0;
|
||||
$onlyActiveLp = !(api_is_platform_admin(true) || api_is_course_admin());
|
||||
$results = learnpath::getLpList($course_id, $session_id, $onlyActiveLp);
|
||||
$data = [];
|
||||
|
||||
if (!empty($results)) {
|
||||
foreach ($results as $lp) {
|
||||
$data[] = ['id' => $lp['id'], 'text' => html_entity_decode($lp['name'])];
|
||||
}
|
||||
}
|
||||
|
||||
echo json_encode($data);
|
||||
break;
|
||||
case 'get_documents':
|
||||
$courseInfo = api_get_course_info();
|
||||
$folderId = $_GET['folder_id'] ?? false;
|
||||
if (empty($folderId)) {
|
||||
exit;
|
||||
}
|
||||
$lpId = isset($_GET['lp_id']) ? $_GET['lp_id'] : false;
|
||||
$url = isset($_GET['url']) ? $_GET['url'] : '';
|
||||
$addMove = isset($_GET['add_move_button']) && $_GET['add_move_button'] == 1 ? true : false;
|
||||
$showOnlyFolders = false;
|
||||
if (isset($_GET['showOnlyFolders'])) {
|
||||
$showOnlyFolders = (1 == (int) $_GET['showOnlyFolders']);
|
||||
}
|
||||
echo DocumentManager::get_document_preview(
|
||||
$courseInfo,
|
||||
$lpId,
|
||||
null,
|
||||
api_get_session_id(),
|
||||
$addMove,
|
||||
null,
|
||||
$url,
|
||||
true,
|
||||
$showOnlyFolders,
|
||||
$folderId,
|
||||
false
|
||||
);
|
||||
break;
|
||||
case 'add_lp_item':
|
||||
if (api_is_allowed_to_edit(null, true)) {
|
||||
/** @var learnpath $learningPath */
|
||||
$learningPath = Session::read('oLP');
|
||||
if ($learningPath) {
|
||||
// Updating the lp.modified_on
|
||||
$learningPath->set_modified_on();
|
||||
$title = $_REQUEST['title'];
|
||||
if ($_REQUEST['type'] == TOOL_QUIZ) {
|
||||
$title = Exercise::format_title_variable($title);
|
||||
}
|
||||
|
||||
$parentId = isset($_REQUEST['parent_id']) ? $_REQUEST['parent_id'] : '';
|
||||
$previousId = isset($_REQUEST['previous_id']) ? $_REQUEST['previous_id'] : '';
|
||||
|
||||
$itemId = $learningPath->add_item(
|
||||
$parentId,
|
||||
$previousId,
|
||||
$_REQUEST['type'],
|
||||
$_REQUEST['id'],
|
||||
$title,
|
||||
null
|
||||
);
|
||||
|
||||
/** @var learnpath $learningPath */
|
||||
$learningPath = Session::read('oLP');
|
||||
if ($learningPath) {
|
||||
echo $learningPath->returnLpItemList(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'update_lp_item_order':
|
||||
if (api_is_allowed_to_edit(null, true)) {
|
||||
// $new_order gets a value like "647|0^648|0^649|0^"
|
||||
$new_order = $_POST['new_order'];
|
||||
$sections = explode('^', $new_order);
|
||||
$sections = array_filter($sections);
|
||||
|
||||
$orderList = [];
|
||||
|
||||
foreach ($sections as $items) {
|
||||
[$id, $parentId] = explode('|', $items);
|
||||
|
||||
$orderList[$id] = $parentId;
|
||||
}
|
||||
|
||||
learnpath::sortItemByOrderList($orderList);
|
||||
|
||||
echo Display::return_message(get_lang('Saved'), 'confirm');
|
||||
}
|
||||
break;
|
||||
case 'record_audio':
|
||||
if (api_is_allowed_to_edit(null, true) == false) {
|
||||
exit;
|
||||
}
|
||||
/** @var Learnpath $lp */
|
||||
$lp = Session::read('oLP');
|
||||
$course_info = api_get_course_info();
|
||||
|
||||
$lpPathInfo = $lp->generate_lp_folder($course_info);
|
||||
|
||||
if (empty($lpPathInfo)) {
|
||||
exit;
|
||||
}
|
||||
|
||||
foreach (['video', 'audio'] as $type) {
|
||||
if (isset($_FILES["${type}-blob"])) {
|
||||
$fileName = $_POST["${type}-filename"];
|
||||
$file = $_FILES["${type}-blob"];
|
||||
$title = $_POST['audio-title'];
|
||||
$fileInfo = pathinfo($fileName);
|
||||
//$file['name'] = 'rec_'.date('Y-m-d_His').'_'.uniqid().'.'.$fileInfo['extension'];
|
||||
$file['name'] = $title.'.'.$fileInfo['extension'];
|
||||
$file['file'] = $file;
|
||||
|
||||
$result = DocumentManager::upload_document(
|
||||
$file,
|
||||
'/audio',
|
||||
$file['name'],
|
||||
null,
|
||||
0,
|
||||
'overwrite',
|
||||
false,
|
||||
false
|
||||
);
|
||||
|
||||
if (!empty($result) && is_array($result)) {
|
||||
$newDocId = $result['id'];
|
||||
$courseId = $result['c_id'];
|
||||
|
||||
$lp->set_modified_on();
|
||||
|
||||
$lpItem = new learnpathItem($_REQUEST['lp_item_id']);
|
||||
$lpItem->add_audio_from_documents($newDocId);
|
||||
$data = DocumentManager::get_document_data_by_id($newDocId, $course_info['code']);
|
||||
echo $data['document_url'];
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case 'get_forum_thread':
|
||||
$lpId = isset($_GET['lp']) ? intval($_GET['lp']) : 0;
|
||||
$lpItemId = isset($_GET['lp_item']) ? intval($_GET['lp_item']) : 0;
|
||||
$sessionId = api_get_session_id();
|
||||
|
||||
if (empty($lpId) || empty($lpItemId)) {
|
||||
echo json_encode([
|
||||
'error' => true,
|
||||
]);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
$learningPath = learnpath::getLpFromSession(
|
||||
api_get_course_id(),
|
||||
$lpId,
|
||||
api_get_user_id()
|
||||
);
|
||||
$lpItem = $learningPath->getItem($lpItemId);
|
||||
|
||||
if (empty($lpItem)) {
|
||||
echo json_encode([
|
||||
'error' => true,
|
||||
]);
|
||||
break;
|
||||
}
|
||||
|
||||
$lpHasForum = $learningPath->lpHasForum();
|
||||
|
||||
if (!$lpHasForum) {
|
||||
echo json_encode([
|
||||
'error' => true,
|
||||
]);
|
||||
break;
|
||||
}
|
||||
|
||||
$forum = $learningPath->getForum($sessionId);
|
||||
|
||||
if (empty($forum)) {
|
||||
require_once '../../forum/forumfunction.inc.php';
|
||||
$forumCategory = getForumCategoryByTitle(
|
||||
get_lang('LearningPaths'),
|
||||
$courseId,
|
||||
$sessionId
|
||||
);
|
||||
|
||||
if (empty($forumCategory)) {
|
||||
$forumCategoryId = store_forumcategory(
|
||||
[
|
||||
'lp_id' => 0,
|
||||
'forum_category_title' => get_lang('LearningPaths'),
|
||||
'forum_category_comment' => null,
|
||||
],
|
||||
[],
|
||||
false
|
||||
);
|
||||
} else {
|
||||
$forumCategoryId = $forumCategory['cat_id'];
|
||||
}
|
||||
|
||||
$forumId = $learningPath->createForum($forumCategoryId);
|
||||
} else {
|
||||
$forumId = $forum['forum_id'];
|
||||
}
|
||||
|
||||
$lpItemHasThread = $lpItem->lpItemHasThread($courseId);
|
||||
|
||||
if (!$lpItemHasThread) {
|
||||
echo json_encode([
|
||||
'error' => true,
|
||||
]);
|
||||
break;
|
||||
}
|
||||
|
||||
$forumThread = $lpItem->getForumThread($courseId, $sessionId);
|
||||
if (empty($forumThread)) {
|
||||
$lpItem->createForumThread($forumId);
|
||||
$forumThread = $lpItem->getForumThread($courseId, $sessionId);
|
||||
}
|
||||
|
||||
$forumThreadId = $forumThread['thread_id'];
|
||||
|
||||
echo json_encode([
|
||||
'error' => false,
|
||||
'forumId' => intval($forum['forum_id']),
|
||||
'threadId' => intval($forumThreadId),
|
||||
]);
|
||||
break;
|
||||
case 'update_gamification':
|
||||
$lp = Session::read('oLP');
|
||||
|
||||
$jsonGamification = [
|
||||
'stars' => 0,
|
||||
'score' => 0,
|
||||
];
|
||||
|
||||
if ($lp) {
|
||||
$score = $lp->getCalculateScore($sessionId);
|
||||
$jsonGamification['stars'] = $lp->getCalculateStars($sessionId);
|
||||
$jsonGamification['score'] = sprintf(get_lang('XPoints'), $score);
|
||||
}
|
||||
|
||||
echo json_encode($jsonGamification);
|
||||
break;
|
||||
case 'check_item_position':
|
||||
$lp = Session::read('oLP');
|
||||
$lpItemId = isset($_GET['lp_item']) ? intval($_GET['lp_item']) : 0;
|
||||
if ($lp) {
|
||||
$position = $lp->isFirstOrLastItem($lpItemId);
|
||||
echo json_encode($position);
|
||||
}
|
||||
break;
|
||||
case 'get_parent_names':
|
||||
$newItemId = isset($_GET['new_item']) ? intval($_GET['new_item']) : 0;
|
||||
|
||||
if (!$newItemId) {
|
||||
break;
|
||||
}
|
||||
|
||||
/** @var \learnpath $lp */
|
||||
$lp = Session::read('oLP');
|
||||
$parentNames = $lp->getCurrentItemParentNames($newItemId);
|
||||
$response = '';
|
||||
foreach ($parentNames as $parentName) {
|
||||
$response .= '<p class="h5 hidden-xs hidden-md">'.$parentName.'</p>';
|
||||
}
|
||||
|
||||
echo $response;
|
||||
break;
|
||||
case 'get_item_prerequisites':
|
||||
/** @var learnpath $lp */
|
||||
$lp = Session::read('oLP');
|
||||
$itemId = isset($_GET['item_id']) ? (int) $_GET['item_id'] : 0;
|
||||
if (empty($lp) || empty($itemId)) {
|
||||
exit;
|
||||
}
|
||||
if ($lp->debug) {
|
||||
error_log('--------------------------------------');
|
||||
error_log('get_item_prerequisites');
|
||||
}
|
||||
|
||||
$result = $lp->prerequisites_match($itemId);
|
||||
if ($result) {
|
||||
echo '1';
|
||||
} else {
|
||||
if (!empty($lp->error)) {
|
||||
echo $lp->error;
|
||||
} else {
|
||||
echo get_lang('LearnpathPrereqNotCompleted');
|
||||
}
|
||||
}
|
||||
$lp->error = '';
|
||||
exit;
|
||||
|
||||
break;
|
||||
default:
|
||||
echo '';
|
||||
}
|
||||
29
main/inc/ajax/mail.ajax.php
Normal file
29
main/inc/ajax/mail.ajax.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
require_once __DIR__.'/../global.inc.php';
|
||||
|
||||
api_protect_admin_script();
|
||||
|
||||
$action = isset($_REQUEST['a']) ? $_REQUEST['a'] : null;
|
||||
|
||||
switch ($action) {
|
||||
case 'select_option':
|
||||
$id = isset($_REQUEST['id']) ? $_REQUEST['id'] : null;
|
||||
if (!empty($id)) {
|
||||
$mail = new MailTemplateManager();
|
||||
$item = $mail->get($id);
|
||||
echo $item['template'];
|
||||
} else {
|
||||
$templateName = isset($_REQUEST['template_name']) ? $_REQUEST['template_name'] : null;
|
||||
if (!empty($templateName)) {
|
||||
$templatePath = api_get_path(SYS_CODE_PATH).'template/default/mail/';
|
||||
if (Security::check_abs_path($templatePath.$templateName, $templatePath)) {
|
||||
if (file_exists($templatePath.$templateName)) {
|
||||
echo file_get_contents($templatePath.$templateName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
170
main/inc/ajax/message.ajax.php
Normal file
170
main/inc/ajax/message.ajax.php
Normal file
@@ -0,0 +1,170 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use Chamilo\UserBundle\Entity\User;
|
||||
|
||||
$_dont_save_user_course_access = true;
|
||||
|
||||
/**
|
||||
* Responses to AJAX calls.
|
||||
*/
|
||||
require_once __DIR__.'/../global.inc.php';
|
||||
|
||||
$action = $_GET['a'];
|
||||
|
||||
switch ($action) {
|
||||
case 'get_count_notifications':
|
||||
if (api_get_configuration_value('notification_event')) {
|
||||
$notificationManager = new NotificationEvent();
|
||||
$notifications = $notificationManager->getNotificationsByUser(api_get_user_id());
|
||||
echo count($notifications);
|
||||
}
|
||||
break;
|
||||
case 'get_notifications':
|
||||
if (api_get_configuration_value('notification_event')) {
|
||||
$notificationManager = new NotificationEvent();
|
||||
$notifications = $notificationManager->getNotificationsByUser(api_get_user_id());
|
||||
echo json_encode($notifications);
|
||||
}
|
||||
break;
|
||||
case 'mark_notification_as_read':
|
||||
if (api_get_configuration_value('notification_event')) {
|
||||
$id = $_REQUEST['id'] ?? 0;
|
||||
$notificationManager = new NotificationEvent();
|
||||
$notificationManager->markAsRead($id);
|
||||
echo 1;
|
||||
}
|
||||
break;
|
||||
case 'get_count_message':
|
||||
api_block_anonymous_users(false);
|
||||
$userId = api_get_user_id();
|
||||
$invitations = MessageManager::getMessagesCountForUser($userId);
|
||||
header('Content-type:application/json');
|
||||
echo json_encode($invitations);
|
||||
break;
|
||||
case 'send_message':
|
||||
api_block_anonymous_users(false);
|
||||
|
||||
$subject = isset($_REQUEST['subject']) ? trim($_REQUEST['subject']) : null;
|
||||
$messageContent = isset($_REQUEST['content']) ? trim($_REQUEST['content']) : null;
|
||||
$messageContent = attr_on_filter($messageContent);
|
||||
|
||||
if (empty($subject) || empty($messageContent)) {
|
||||
echo Display::return_message(get_lang('ErrorSendingMessage'), 'error');
|
||||
exit;
|
||||
}
|
||||
|
||||
$courseId = isset($_REQUEST['course_id']) ? (int) $_REQUEST['course_id'] : 0;
|
||||
$sessionId = isset($_REQUEST['session_id']) ? (int) $_REQUEST['session_id'] : 0;
|
||||
|
||||
// Add course info
|
||||
if (!empty($courseId)) {
|
||||
$courseInfo = api_get_course_info_by_id($courseId);
|
||||
if (!empty($courseInfo)) {
|
||||
if (empty($sessionId)) {
|
||||
$courseNotification = sprintf(get_lang('ThisEmailWasSentViaCourseX'), $courseInfo['title']);
|
||||
} else {
|
||||
$sessionInfo = api_get_session_info($sessionId);
|
||||
if (!empty($sessionInfo)) {
|
||||
$courseNotification = sprintf(
|
||||
get_lang('ThisEmailWasSentViaCourseXInSessionX'),
|
||||
$courseInfo['title'],
|
||||
$sessionInfo['name']
|
||||
);
|
||||
}
|
||||
}
|
||||
$messageContent .= '<br /><br />'.$courseNotification;
|
||||
}
|
||||
}
|
||||
|
||||
$result = MessageManager::send_message($_REQUEST['user_id'], $subject, $messageContent);
|
||||
if ($result) {
|
||||
echo Display::return_message(get_lang('MessageHasBeenSent'), 'confirmation');
|
||||
} else {
|
||||
echo Display::return_message(get_lang('ErrorSendingMessage'), 'confirmation');
|
||||
}
|
||||
break;
|
||||
case 'send_invitation':
|
||||
api_block_anonymous_users(false);
|
||||
|
||||
$subject = isset($_REQUEST['subject']) ? trim($_REQUEST['subject']) : null;
|
||||
$invitationContent = isset($_REQUEST['content']) ? trim($_REQUEST['content']) : null;
|
||||
|
||||
SocialManager::sendInvitationToUser($_REQUEST['user_id'], $subject, $invitationContent);
|
||||
break;
|
||||
case 'find_users':
|
||||
if (api_is_anonymous()) {
|
||||
echo '';
|
||||
break;
|
||||
}
|
||||
|
||||
$repo = UserManager::getRepository();
|
||||
$users = $repo->findUsersToSendMessage(
|
||||
api_get_user_id(),
|
||||
$_REQUEST['q'],
|
||||
$_REQUEST['page_limit']
|
||||
);
|
||||
|
||||
$showEmail = api_get_setting('show_email_addresses') === 'true';
|
||||
$return = ['items' => []];
|
||||
|
||||
/** @var User $user */
|
||||
foreach ($users as $user) {
|
||||
$userName = UserManager::formatUserFullName($user, true);
|
||||
|
||||
if ($showEmail) {
|
||||
$userName .= " ({$user->getEmail()})";
|
||||
}
|
||||
|
||||
$return['items'][] = [
|
||||
'text' => $userName,
|
||||
'id' => $user->getId(),
|
||||
];
|
||||
}
|
||||
header('Content-type:application/json');
|
||||
echo json_encode($return);
|
||||
break;
|
||||
case 'add_tags':
|
||||
$idList = $_POST['id'] ?? [];
|
||||
$tagList = $_POST['tags'] ?? [];
|
||||
|
||||
if (false === api_get_configuration_value('enable_message_tags')
|
||||
|| api_is_anonymous()
|
||||
|| api_get_setting('allow_message_tool') !== 'true'
|
||||
|| empty($idList) || empty($tagList)
|
||||
) {
|
||||
break;
|
||||
}
|
||||
|
||||
$em = Database::getManager();
|
||||
$userId = api_get_user_id();
|
||||
|
||||
$extraFieldValues = new ExtraFieldValue('message');
|
||||
|
||||
foreach ($idList as $messageId) {
|
||||
$messageInfo = MessageManager::get_message_by_id($messageId);
|
||||
|
||||
if ($messageInfo['msg_status'] == MESSAGE_STATUS_OUTBOX
|
||||
&& $messageInfo['user_sender_id'] != $userId
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (in_array($messageInfo['msg_status'], [MESSAGE_STATUS_UNREAD, MESSAGE_STATUS_NEW])
|
||||
&& $messageInfo['user_receiver_id'] != $userId
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$extraParams = [
|
||||
'item_id' => $messageInfo['id'],
|
||||
'extra_tags' => $tagList,
|
||||
];
|
||||
|
||||
$extraFieldValues->saveFieldValues($extraParams, false, false, ['tags'], [], false, false);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
echo '';
|
||||
}
|
||||
exit;
|
||||
2816
main/inc/ajax/model.ajax.php
Normal file
2816
main/inc/ajax/model.ajax.php
Normal file
File diff suppressed because it is too large
Load Diff
232
main/inc/ajax/myspace.ajax.php
Normal file
232
main/inc/ajax/myspace.ajax.php
Normal file
@@ -0,0 +1,232 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Responses to AJAX calls.
|
||||
*/
|
||||
require_once __DIR__.'/../global.inc.php';
|
||||
|
||||
$action = $_GET['a'];
|
||||
|
||||
// Access restrictions.
|
||||
$is_allowedToTrack = api_is_platform_admin(true, true) ||
|
||||
api_is_allowed_to_create_course() || api_is_course_tutor() || api_is_session_general_coach();
|
||||
|
||||
if (!$is_allowedToTrack) {
|
||||
exit;
|
||||
}
|
||||
|
||||
switch ($action) {
|
||||
case 'lp_global_report':
|
||||
$userId = (int) $_REQUEST['user_id'];
|
||||
if (empty($userId)) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$cacheAvailable = api_get_configuration_value('apc');
|
||||
$table = null;
|
||||
$variable = 'lp_global_report_'.$userId;
|
||||
if ($cacheAvailable) {
|
||||
if (apcu_exists($variable)) {
|
||||
$table = apcu_fetch($variable);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($table)) {
|
||||
echo $table;
|
||||
exit;
|
||||
}
|
||||
|
||||
$sessionCategoryList = UserManager::get_sessions_by_category($userId, false);
|
||||
$total = 0;
|
||||
$totalAverage = 0;
|
||||
$table = new HTML_Table(['class' => 'table table-hover table-striped data_table']);
|
||||
$row = 0;
|
||||
$col = 0;
|
||||
foreach ($sessionCategoryList as $category) {
|
||||
$sessionList = $category['sessions'];
|
||||
foreach ($sessionList as $session) {
|
||||
$courses = $session['courses'];
|
||||
$sessionId = $session['session_id'];
|
||||
$session['session_name'];
|
||||
$totalCourse = 0;
|
||||
$totalSessionAverage = 0;
|
||||
foreach ($courses as &$course) {
|
||||
$average = Tracking::get_avg_student_progress($userId, $course['course_code'], [], $sessionId);
|
||||
$totalSessionAverage += $average;
|
||||
$totalCourse++;
|
||||
if (false !== $average) {
|
||||
$average = $average.' %';
|
||||
}
|
||||
$course['average'] = $average;
|
||||
}
|
||||
|
||||
$total++;
|
||||
$totalSessionAverage = round($totalSessionAverage / count($courses), 2);
|
||||
$totalAverage += $totalSessionAverage;
|
||||
|
||||
$row++;
|
||||
$table->setCellContents($row, 0, $session['session_name']);
|
||||
$table->setCellContents($row, 1, $totalSessionAverage.' %');
|
||||
$table->setCellContents($row, 2, '');
|
||||
$row++;
|
||||
foreach ($courses as &$course) {
|
||||
$table->setCellContents($row, 0, $session['session_name']);
|
||||
$table->setCellContents($row, 1, $course['title']);
|
||||
$table->setCellContents($row, 2, $course['average']);
|
||||
$row++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$table->setCellContents(0, 0, get_lang('Global'));
|
||||
$table->setCellContents(0, 1, round($totalAverage / $total, 2).' %');
|
||||
$result = $table->toHtml();
|
||||
|
||||
if ($cacheAvailable) {
|
||||
apcu_store($variable, $result, 60);
|
||||
}
|
||||
|
||||
echo $result;
|
||||
|
||||
break;
|
||||
case 'access_detail':
|
||||
// At this date : 23/02/2017, a minor review can't determine where is used this case 'access_detail'.
|
||||
$user_id = (int) $_REQUEST['student'];
|
||||
$course_code = Security::remove_XSS($_REQUEST['course']);
|
||||
$type = Security::remove_XSS($_REQUEST['type']);
|
||||
$range = Security::remove_XSS($_REQUEST['range']);
|
||||
$sessionId = isset($_REQUEST['session_id']) ? $_REQUEST['session_id'] : 0;
|
||||
$courseInfo = api_get_course_info($course_code);
|
||||
|
||||
if ($range == 1) {
|
||||
$start_date = Security::remove_XSS($_REQUEST['sd']);
|
||||
$end_date = Security::remove_XSS($_REQUEST['ed']);
|
||||
$sql_result = MySpace::get_connections_to_course_by_date(
|
||||
$user_id,
|
||||
$courseInfo,
|
||||
$sessionId,
|
||||
$start_date,
|
||||
$end_date
|
||||
);
|
||||
} else {
|
||||
$sql_result = MySpace::get_connections_to_course(
|
||||
$user_id,
|
||||
$courseInfo,
|
||||
$sessionId
|
||||
);
|
||||
}
|
||||
$foo_print = MySpace::grapher($sql_result, $start_date, $end_date, $type);
|
||||
echo $foo_print;
|
||||
|
||||
break;
|
||||
case 'access_detail_by_date':
|
||||
$export = isset($_REQUEST['export']) ? $_REQUEST['export'] : false;
|
||||
|
||||
$result = ['is_empty' => true];
|
||||
$start_date = isset($_REQUEST['startDate']) ? $_REQUEST['startDate'] : '';
|
||||
$end_date = isset($_REQUEST['endDate']) ? $_REQUEST['endDate'] : '';
|
||||
$user_id = isset($_REQUEST['student']) ? $_REQUEST['student'] : '';
|
||||
$course_code = isset($_REQUEST['course']) ? $_REQUEST['course'] : '';
|
||||
$type = isset($_REQUEST['type']) ? $_REQUEST['type'] : '';
|
||||
$sessionId = isset($_REQUEST['session_id']) ? $_REQUEST['session_id'] : 0;
|
||||
$courseInfo = api_get_course_info($course_code);
|
||||
|
||||
$connections = MySpace::get_connections_to_course_by_date(
|
||||
$user_id,
|
||||
$courseInfo,
|
||||
$sessionId,
|
||||
$start_date,
|
||||
$end_date,
|
||||
true
|
||||
);
|
||||
|
||||
if (is_array($connections) && count($connections) > 0) {
|
||||
$result['is_empty'] = false;
|
||||
$tableData = [];
|
||||
foreach ($connections as $data) {
|
||||
$item = [
|
||||
api_get_local_time($data['login']),
|
||||
api_time_to_hms(api_strtotime($data['logout']) - api_strtotime($data['login'])),
|
||||
$data['user_ip'],
|
||||
];
|
||||
$tableData[] = $item;
|
||||
}
|
||||
|
||||
$table = new SortableTableFromArray(
|
||||
$tableData,
|
||||
0,
|
||||
500,
|
||||
'stat_table',
|
||||
null,
|
||||
'stat_table'
|
||||
);
|
||||
$table->set_header(1, get_lang('LoginDate'), false);
|
||||
$table->set_header(2, get_lang('Duration'), false);
|
||||
$table->set_header(3, get_lang('IP'), false);
|
||||
$result['result'] = $table->return_table();
|
||||
|
||||
if ($export) {
|
||||
Export::arrayToXls($table->toArray());
|
||||
exit;
|
||||
}
|
||||
|
||||
$rst = MySpace::getStats(
|
||||
$user_id,
|
||||
$courseInfo,
|
||||
$sessionId,
|
||||
$start_date,
|
||||
$end_date
|
||||
);
|
||||
$stats = '<strong>'.get_lang('Total').': </strong>'.$rst['total'].'<br />';
|
||||
$stats .= '<strong>'.get_lang('Average').': </strong>'.$rst['avg'].'<br />';
|
||||
$stats .= '<strong>'.get_lang('Quantity').' : </strong>'.$rst['times'].'<br />';
|
||||
$result['stats'] = $stats;
|
||||
$result['graph_result'] = MySpace::grapher($connections, $start_date, $end_date, $type);
|
||||
} else {
|
||||
$result['result'] = Display::return_message(
|
||||
get_lang('NoDataAvailable'),
|
||||
'warning'
|
||||
);
|
||||
$result['graph_result'] = Display::return_message(
|
||||
get_lang('NoDataAvailable'),
|
||||
'warning'
|
||||
);
|
||||
$result['stats'] = Display::return_message(
|
||||
get_lang('NoDataAvailable'),
|
||||
'warning'
|
||||
);
|
||||
}
|
||||
header('Cache-Control: no-cache');
|
||||
echo json_encode($result);
|
||||
break;
|
||||
case 'show_conditional_to_export_pdf':
|
||||
$studentId = isset($_REQUEST['student']) ? (int) $_REQUEST['student'] : 0;
|
||||
$sId = isset($_REQUEST['session_to_export']) ? (int) $_REQUEST['session_to_export'] : 0;
|
||||
|
||||
$form = new FormValidator(
|
||||
'conditional_to_export_pdf',
|
||||
'post',
|
||||
api_get_path(WEB_CODE_PATH).'mySpace/session.php?'
|
||||
.http_build_query(
|
||||
[
|
||||
'student' => $studentId,
|
||||
'action' => 'export_to_pdf',
|
||||
'type' => 'achievement',
|
||||
'session_to_export' => $sId,
|
||||
]
|
||||
),
|
||||
'',
|
||||
[],
|
||||
FormValidator::LAYOUT_INLINE
|
||||
);
|
||||
|
||||
$form->addCheckBox('hide_connection_time', null, get_lang('HideConnectionTime'));
|
||||
$form->addHtml('<br><br>');
|
||||
$form->addButtonSave(get_lang('Generate'), 'submitLink');
|
||||
$content = $form->returnForm();
|
||||
echo $content;
|
||||
break;
|
||||
}
|
||||
exit;
|
||||
45
main/inc/ajax/online.ajax.php
Normal file
45
main/inc/ajax/online.ajax.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
$_dont_save_user_course_access = true;
|
||||
|
||||
require_once __DIR__.'/../global.inc.php';
|
||||
|
||||
$action = isset($_GET['a']) ? $_GET['a'] : '';
|
||||
|
||||
switch ($action) {
|
||||
case 'get_users_online':
|
||||
echo returnNotificationMenu();
|
||||
break;
|
||||
case 'load_online_user':
|
||||
$access = accessToWhoIsOnline();
|
||||
|
||||
if (!$access) {
|
||||
exit;
|
||||
}
|
||||
$images_to_show = MAX_ONLINE_USERS;
|
||||
$page = intval($_REQUEST['online_page_nr']);
|
||||
$max_page = ceil(who_is_online_count() / $images_to_show);
|
||||
$page_rows = ($page - 1) * MAX_ONLINE_USERS;
|
||||
if (!empty($max_page) && $page <= $max_page) {
|
||||
if (isset($_GET['cidReq']) && strlen($_GET['cidReq']) > 0) {
|
||||
$user_list = who_is_online_in_this_course(
|
||||
$page_rows,
|
||||
$images_to_show,
|
||||
api_get_user_id(),
|
||||
api_get_setting('time_limit_whosonline'),
|
||||
$_GET['cidReq']
|
||||
);
|
||||
} else {
|
||||
$user_list = who_is_online($page_rows, $images_to_show);
|
||||
}
|
||||
if (!empty($user_list)) {
|
||||
echo SocialManager::display_user_list($user_list, false);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
echo 'end';
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
39
main/inc/ajax/plugin.ajax.php
Normal file
39
main/inc/ajax/plugin.ajax.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
use Michelf\MarkdownExtra;
|
||||
|
||||
/**
|
||||
* Responses to AJAX calls.
|
||||
*/
|
||||
require_once __DIR__.'/../global.inc.php';
|
||||
|
||||
api_block_anonymous_users();
|
||||
|
||||
$action = $_REQUEST['a'];
|
||||
|
||||
switch ($action) {
|
||||
case 'md_to_html':
|
||||
$plugin = $_GET['plugin'] ?? '';
|
||||
$appPlugin = new AppPlugin();
|
||||
|
||||
$pluginPaths = $appPlugin->read_plugins_from_path();
|
||||
|
||||
if (!in_array($plugin, $pluginPaths)) {
|
||||
echo Display::return_message(get_lang('NotAllowed'), 'error', false);
|
||||
exit;
|
||||
}
|
||||
|
||||
$pluginInfo = $appPlugin->getPluginInfo($plugin);
|
||||
|
||||
$html = '';
|
||||
if (!empty($pluginInfo)) {
|
||||
$file = api_get_path(SYS_PLUGIN_PATH).$plugin.'/README.md';
|
||||
if (file_exists($file)) {
|
||||
$content = file_get_contents($file);
|
||||
|
||||
$html = MarkdownExtra::defaultTransform($content);
|
||||
}
|
||||
}
|
||||
echo $html;
|
||||
break;
|
||||
}
|
||||
79
main/inc/ajax/portfolio.ajax.php
Normal file
79
main/inc/ajax/portfolio.ajax.php
Normal file
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use Chamilo\CoreBundle\Entity\Portfolio;
|
||||
use Chamilo\CoreBundle\Entity\PortfolioComment;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Request as HttpRequest;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
require_once __DIR__.'/../global.inc.php';
|
||||
|
||||
$httpRequest = HttpRequest::createFromGlobals();
|
||||
|
||||
$action = $httpRequest->query->has('a') ? $httpRequest->query->get('a') : $httpRequest->request->get('a');
|
||||
$currentUserId = api_get_user_id();
|
||||
$currentUser = api_get_user_entity($currentUserId);
|
||||
|
||||
$em = Database::getManager();
|
||||
|
||||
$item = null;
|
||||
$comment = null;
|
||||
|
||||
if ($httpRequest->query->has('item')) {
|
||||
/** @var Portfolio $item */
|
||||
$item = $em->find(
|
||||
Portfolio::class,
|
||||
$httpRequest->query->getInt('item')
|
||||
);
|
||||
}
|
||||
|
||||
if ($httpRequest->query->has('comment')) {
|
||||
$comment = $em->find(
|
||||
PortfolioComment::class,
|
||||
$httpRequest->query->getInt('comment')
|
||||
);
|
||||
}
|
||||
|
||||
$httpResponse = Response::create();
|
||||
|
||||
switch ($action) {
|
||||
case 'find_template':
|
||||
if (!$item) {
|
||||
$httpResponse->setStatusCode(Response::HTTP_NOT_FOUND);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!$item->isTemplate() || $item->getUser() !== $currentUser) {
|
||||
$httpResponse->setStatusCode(Response::HTTP_FORBIDDEN);
|
||||
break;
|
||||
}
|
||||
|
||||
$httpResponse = JsonResponse::create(
|
||||
[
|
||||
'title' => $item->getTitle(),
|
||||
'content' => $item->getContent(),
|
||||
]
|
||||
);
|
||||
break;
|
||||
case 'find_template_comment':
|
||||
if (!$comment) {
|
||||
$httpResponse->setStatusCode(Response::HTTP_NOT_FOUND);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!$comment->isTemplate() || $comment->getAuthor() !== $currentUser) {
|
||||
$httpResponse->setStatusCode(Response::HTTP_FORBIDDEN);
|
||||
break;
|
||||
}
|
||||
|
||||
$httpResponse = JsonResponse::create(
|
||||
[
|
||||
'content' => $comment->getContent(),
|
||||
]
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
$httpResponse->send();
|
||||
110
main/inc/ajax/record_audio_rtc.ajax.php
Normal file
110
main/inc/ajax/record_audio_rtc.ajax.php
Normal file
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use ChamiloSession as Session;
|
||||
|
||||
require_once __DIR__.'/../global.inc.php';
|
||||
|
||||
api_block_anonymous_users();
|
||||
|
||||
$courseInfo = api_get_course_info();
|
||||
/** @var string $tool document or exercise */
|
||||
$tool = isset($_REQUEST['tool']) ? $_REQUEST['tool'] : '';
|
||||
$type = isset($_REQUEST['type']) ? $_REQUEST['type'] : 'document'; // can be document or message
|
||||
|
||||
if ($type === 'document') {
|
||||
api_protect_course_script();
|
||||
}
|
||||
|
||||
$userId = api_get_user_id();
|
||||
|
||||
if (!isset($_FILES['audio_blob'], $_REQUEST['audio_dir'])) {
|
||||
if ($tool === 'exercise') {
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode([
|
||||
'error' => true,
|
||||
'message' => Display::return_message(get_lang('UploadError'), 'error'),
|
||||
]);
|
||||
|
||||
Display::cleanFlashMessages();
|
||||
exit;
|
||||
}
|
||||
|
||||
Display::addFlash(Display::return_message(get_lang('UploadError'), 'error'));
|
||||
exit;
|
||||
}
|
||||
|
||||
$file = isset($_FILES['audio_blob']) ? $_FILES['audio_blob'] : [];
|
||||
$file['file'] = $file;
|
||||
$audioDir = Security::remove_XSS($_REQUEST['audio_dir']);
|
||||
|
||||
switch ($type) {
|
||||
case 'document':
|
||||
$dirBaseDocuments = api_get_path(SYS_COURSE_PATH).$courseInfo['path'].'/document';
|
||||
$saveDir = $dirBaseDocuments.$audioDir;
|
||||
if (!is_dir($saveDir)) {
|
||||
mkdir($saveDir, api_get_permissions_for_new_directories(), true);
|
||||
}
|
||||
|
||||
if (empty($audioDir)) {
|
||||
$audioDir = '/';
|
||||
}
|
||||
|
||||
$uploadedDocument = DocumentManager::upload_document(
|
||||
$file,
|
||||
$audioDir,
|
||||
$file['name'],
|
||||
null,
|
||||
0,
|
||||
'overwrite',
|
||||
false,
|
||||
in_array($tool, ['document', 'exercise']),
|
||||
'file',
|
||||
true,
|
||||
api_get_user_id(),
|
||||
$courseInfo,
|
||||
api_get_session_id(),
|
||||
api_get_group_id(),
|
||||
'exercise' === $tool
|
||||
);
|
||||
$error = empty($uploadedDocument) || !is_array($uploadedDocument);
|
||||
|
||||
if (!$error) {
|
||||
$newDocId = $uploadedDocument['id'];
|
||||
$courseId = $uploadedDocument['c_id'];
|
||||
|
||||
/** @var learnpath $lp */
|
||||
$lp = Session::read('oLP');
|
||||
$lpItemId = isset($_REQUEST['lp_item_id']) && !empty($_REQUEST['lp_item_id']) ? $_REQUEST['lp_item_id'] : null;
|
||||
if (!empty($lp) && empty($lpItemId)) {
|
||||
$lp->set_modified_on();
|
||||
|
||||
$lpItem = new learnpathItem($lpItemId);
|
||||
$lpItem->add_audio_from_documents($newDocId);
|
||||
}
|
||||
|
||||
$data = DocumentManager::get_document_data_by_id($newDocId, $courseInfo['code']);
|
||||
|
||||
if ($tool === 'exercise') {
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode([
|
||||
'error' => $error,
|
||||
'message' => Display::getFlashToString(),
|
||||
'fileUrl' => $data['document_url'],
|
||||
]);
|
||||
|
||||
Display::cleanFlashMessages();
|
||||
exit;
|
||||
}
|
||||
|
||||
echo $data['document_url'];
|
||||
}
|
||||
|
||||
break;
|
||||
case 'message':
|
||||
Session::write('current_audio_id', $file['name']);
|
||||
api_upload_file('audio_message', $file, api_get_user_id());
|
||||
|
||||
break;
|
||||
}
|
||||
155
main/inc/ajax/record_audio_wami.ajax.php
Normal file
155
main/inc/ajax/record_audio_wami.ajax.php
Normal file
@@ -0,0 +1,155 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use ChamiloSession as Session;
|
||||
|
||||
require_once __DIR__.'/../global.inc.php';
|
||||
|
||||
// Add security from Chamilo
|
||||
api_block_anonymous_users();
|
||||
|
||||
$_course = api_get_course_info();
|
||||
|
||||
// Save the audio to a URL-accessible directory for playback.
|
||||
parse_str($_SERVER['QUERY_STRING'], $params);
|
||||
|
||||
if (isset($params['waminame']) && isset($params['wamidir']) && isset($params['wamiuserid'])) {
|
||||
$waminame = $params['waminame'];
|
||||
$wamidir = $params['wamidir'];
|
||||
$wamiuserid = $params['wamiuserid'];
|
||||
} else {
|
||||
api_not_allowed();
|
||||
exit();
|
||||
}
|
||||
|
||||
if (empty($wamiuserid)) {
|
||||
api_not_allowed();
|
||||
exit();
|
||||
}
|
||||
|
||||
$type = isset($_REQUEST['type']) ? $_REQUEST['type'] : 'document'; // can be document or message
|
||||
|
||||
if ($type === 'document') {
|
||||
api_protect_course_script();
|
||||
}
|
||||
|
||||
// Clean
|
||||
$waminame = Security::remove_XSS($waminame);
|
||||
$waminame = Database::escape_string($waminame);
|
||||
$waminame = api_replace_dangerous_char($waminame);
|
||||
$waminame = disable_dangerous_file($waminame);
|
||||
$wamidir = Security::remove_XSS($wamidir);
|
||||
$content = file_get_contents('php://input');
|
||||
|
||||
if (empty($content)) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$ext = explode('.', $waminame);
|
||||
$ext = strtolower($ext[sizeof($ext) - 1]);
|
||||
|
||||
if ($ext != 'wav') {
|
||||
exit();
|
||||
}
|
||||
|
||||
switch ($type) {
|
||||
case 'document':
|
||||
// Do not use here check Fileinfo method because return: text/plain
|
||||
$dirBaseDocuments = api_get_path(SYS_COURSE_PATH).$_course['path'].'/document';
|
||||
$saveDir = $dirBaseDocuments.$wamidir;
|
||||
|
||||
if (!is_dir($saveDir)) {
|
||||
DocumentManager::createDefaultAudioFolder($_course);
|
||||
}
|
||||
|
||||
// Avoid duplicates
|
||||
$waminame_to_save = $waminame;
|
||||
$documentPath = $saveDir.'/'.$waminame_to_save;
|
||||
|
||||
// Add to disk
|
||||
$fh = fopen($documentPath, 'w') or exit("can't open file");
|
||||
fwrite($fh, $content);
|
||||
fclose($fh);
|
||||
|
||||
$fileInfo = pathinfo($documentPath);
|
||||
$courseInfo = api_get_course_info();
|
||||
|
||||
$file = [
|
||||
'file' => [
|
||||
'name' => $fileInfo['basename'],
|
||||
'tmp_name' => $documentPath,
|
||||
'size' => filesize($documentPath),
|
||||
'type' => 'audio/wav',
|
||||
'from_file' => true,
|
||||
],
|
||||
];
|
||||
$output = true;
|
||||
ob_start();
|
||||
|
||||
// Strangely the file path changes with a double extension
|
||||
copy($documentPath, $documentPath.'.wav');
|
||||
|
||||
$documentData = DocumentManager::upload_document(
|
||||
$file,
|
||||
$wamidir,
|
||||
$fileInfo['basename'],
|
||||
'wav',
|
||||
0,
|
||||
'overwrite',
|
||||
false,
|
||||
$output
|
||||
);
|
||||
$contents = ob_get_contents();
|
||||
|
||||
if (!empty($documentData)) {
|
||||
$newDocId = $documentData['id'];
|
||||
$documentData['comment'] = 'mp3';
|
||||
$newMp3DocumentId = DocumentManager::addAndConvertWavToMp3(
|
||||
$documentData,
|
||||
$courseInfo,
|
||||
api_get_session_id(),
|
||||
api_get_user_id(),
|
||||
'overwrite',
|
||||
true
|
||||
);
|
||||
|
||||
if ($newMp3DocumentId) {
|
||||
$newDocId = $newMp3DocumentId;
|
||||
}
|
||||
|
||||
if (isset($_REQUEST['lp_item_id']) && !empty($_REQUEST['lp_item_id'])) {
|
||||
$lpItemId = $_REQUEST['lp_item_id'];
|
||||
/** @var learnpath $lp */
|
||||
$lp = Session::read('oLP');
|
||||
|
||||
if (!empty($lp)) {
|
||||
$lp->set_modified_on();
|
||||
$lpItem = new learnpathItem($lpItemId);
|
||||
$lpItem->add_audio_from_documents($newDocId);
|
||||
echo Display::return_message(get_lang('Updated'), 'info');
|
||||
}
|
||||
}
|
||||
|
||||
// Strangely the file path changes with a double extension
|
||||
// Remove file with one extension
|
||||
unlink($documentPath);
|
||||
} else {
|
||||
echo $contents;
|
||||
}
|
||||
|
||||
break;
|
||||
case 'message':
|
||||
$tempFile = api_get_path(SYS_ARCHIVE_PATH).$waminame;
|
||||
file_put_contents($tempFile, $content);
|
||||
|
||||
Session::write('current_audio_id', $waminame);
|
||||
$file = [
|
||||
'name' => basename($tempFile),
|
||||
'tmp_name' => $tempFile,
|
||||
'size' => filesize($tempFile),
|
||||
'type' => 'audio/wav',
|
||||
'move_file' => true,
|
||||
];
|
||||
api_upload_file('audio_message', $file, api_get_user_id());
|
||||
break;
|
||||
}
|
||||
474
main/inc/ajax/sequence.ajax.php
Normal file
474
main/inc/ajax/sequence.ajax.php
Normal file
@@ -0,0 +1,474 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use Chamilo\CoreBundle\Entity\Repository\SequenceRepository;
|
||||
use Chamilo\CoreBundle\Entity\Repository\SequenceResourceRepository;
|
||||
use Chamilo\CoreBundle\Entity\Sequence;
|
||||
use Chamilo\CoreBundle\Entity\SequenceResource;
|
||||
use ChamiloSession as Session;
|
||||
use Fhaculty\Graph\Graph;
|
||||
use Fhaculty\Graph\Vertex;
|
||||
use Graphp\GraphViz\GraphViz;
|
||||
|
||||
/**
|
||||
* Responses to AJAX calls.
|
||||
*/
|
||||
require_once __DIR__.'/../global.inc.php';
|
||||
|
||||
$action = $_REQUEST['a'] ?? null;
|
||||
$id = (int) ($_REQUEST['id'] ?? null);
|
||||
$type = (int) ($_REQUEST['type'] ?? null);
|
||||
$sequenceId = $_REQUEST['sequence_id'] ?? 0;
|
||||
|
||||
$em = Database::getManager();
|
||||
/** @var SequenceRepository $sequenceRepository */
|
||||
$sequenceRepository = $em->getRepository(Sequence::class);
|
||||
/** @var SequenceResourceRepository $sequenceResourceRepository */
|
||||
$sequenceResourceRepository = $em->getRepository(SequenceResource::class);
|
||||
|
||||
switch ($action) {
|
||||
case 'graph':
|
||||
api_block_anonymous_users();
|
||||
|
||||
/** @var Sequence $sequence */
|
||||
$sequence = $sequenceRepository->find($sequenceId);
|
||||
|
||||
if (null === $sequence) {
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($sequence->hasGraph()) {
|
||||
$graph = $sequence->getUnSerializeGraph();
|
||||
$graph->setAttribute('graphviz.node.fontname', 'arial');
|
||||
$graphviz = new GraphViz();
|
||||
$graphImage = '';
|
||||
try {
|
||||
$graphImage = $graphviz->createImageSrc($graph);
|
||||
echo Display::img(
|
||||
$graphImage,
|
||||
get_lang('GraphDependencyTree'),
|
||||
['class' => 'center-block img-responsive'],
|
||||
false
|
||||
);
|
||||
} catch (UnexpectedValueException $e) {
|
||||
error_log(
|
||||
$e->getMessage()
|
||||
.' - Graph could not be rendered in resources sequence'
|
||||
.' because GraphViz command "dot" could not be executed '
|
||||
.'- Make sure graphviz is installed.'
|
||||
);
|
||||
echo '<p class="text-center"><small>'.get_lang('MissingChartLibraryPleaseCheckLog')
|
||||
.'</small></p>';
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case 'get_icon':
|
||||
api_block_anonymous_users();
|
||||
api_protect_admin_script();
|
||||
|
||||
$showDelete = $_REQUEST['show_delete'] ?? false;
|
||||
$image = Display::return_icon('item-sequence.png', null, null, ICON_SIZE_LARGE);
|
||||
|
||||
if (empty($id)) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$link = '';
|
||||
$linkDelete = $linkUndo = '';
|
||||
$resourceName = '';
|
||||
switch ($type) {
|
||||
case SequenceResource::SESSION_TYPE:
|
||||
$resourceData = api_get_session_info($id);
|
||||
if ($resourceData) {
|
||||
$resourceName = $resourceData['name'];
|
||||
}
|
||||
break;
|
||||
case SequenceResource::COURSE_TYPE:
|
||||
$resourceData = api_get_course_info_by_id($id);
|
||||
if ($resourceData) {
|
||||
$resourceName = $resourceData['name'];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (empty($resourceData)) {
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($showDelete) {
|
||||
$linkDelete = Display::toolbarButton(
|
||||
get_lang('Delete'),
|
||||
'#',
|
||||
'trash',
|
||||
'default',
|
||||
[
|
||||
'class' => 'delete_vertex btn btn-block btn-xs',
|
||||
'data-id' => $id,
|
||||
]
|
||||
);
|
||||
|
||||
$linkUndo = Display::toolbarButton(
|
||||
get_lang('Undo'),
|
||||
'#',
|
||||
'undo',
|
||||
'default',
|
||||
[
|
||||
'class' => 'undo_delete btn btn-block btn-xs',
|
||||
'style' => 'display: none;',
|
||||
'data-id' => $id,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
$link = '<div class="parent" data-id="'.$id.'">';
|
||||
$link .= '<div class="big-icon">';
|
||||
$link .= $image;
|
||||
$link .= '<div class="sequence-course">'.$resourceName.'</div>';
|
||||
$link .= Display::tag(
|
||||
'button',
|
||||
$resourceName,
|
||||
[
|
||||
'class' => 'sequence-id',
|
||||
'title' => get_lang('UseAsReference'),
|
||||
'type' => 'button',
|
||||
]
|
||||
);
|
||||
$link .= $linkDelete;
|
||||
$link .= $linkUndo;
|
||||
$link .= '</div></div>';
|
||||
|
||||
echo $link;
|
||||
break;
|
||||
case 'delete_vertex':
|
||||
api_block_anonymous_users();
|
||||
api_protect_admin_script();
|
||||
|
||||
$vertexId = $_REQUEST['vertex_id'] ?? null;
|
||||
|
||||
/** @var Sequence $sequence */
|
||||
$sequence = $sequenceRepository->find($sequenceId);
|
||||
|
||||
if (null === $sequence) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/** @var SequenceResource $sequenceResource */
|
||||
$sequenceResource = $sequenceResourceRepository->findOneBy(
|
||||
['resourceId' => $id, 'type' => $type, 'sequence' => $sequence]
|
||||
);
|
||||
|
||||
if (null === $sequenceResource) {
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($sequenceResource->getSequence()->hasGraph()) {
|
||||
$graph = $sequenceResource->getSequence()->getUnSerializeGraph();
|
||||
if ($graph->hasVertex($vertexId)) {
|
||||
$edgeIterator = $graph->getEdges()->getIterator();
|
||||
$edgeToDelete = null;
|
||||
foreach ($edgeIterator as $edge) {
|
||||
if ($edge->getVertexStart()->getId() == $vertexId && $edge->getVertexEnd()->getId() == $id) {
|
||||
$edgeToDelete = $edge;
|
||||
$vertexFromTo = null;
|
||||
$vertexToFrom = null;
|
||||
foreach ($edgeIterator as $edges) {
|
||||
if ((int) $edges->getVertexEnd()->getId() === (int) $id) {
|
||||
$vertexFromTo = $edges;
|
||||
}
|
||||
|
||||
if ((int) $edges->getVertexStart()->getId() === (int) $vertexId) {
|
||||
$vertexToFrom = $edges;
|
||||
}
|
||||
}
|
||||
|
||||
if ($vertexFromTo && !$vertexToFrom) {
|
||||
Session::write('sr_vertex', true);
|
||||
$vertex = $graph->getVertex($id);
|
||||
$vertex->destroy();
|
||||
$em->remove($sequenceResource);
|
||||
}
|
||||
|
||||
if ($vertexToFrom && $vertexFromTo) {
|
||||
$vertex = $graph->getVertex($vertexId);
|
||||
$edgeToDelete->destroy();
|
||||
}
|
||||
|
||||
if ($vertexToFrom && !$vertexFromTo) {
|
||||
$vertex = $graph->getVertex($vertexId);
|
||||
$vertex->destroy();
|
||||
$sequenceResourceToDelete = $sequenceResourceRepository->findOneBy(
|
||||
[
|
||||
'resourceId' => $vertexId,
|
||||
'type' => $type,
|
||||
'sequence' => $sequence,
|
||||
]
|
||||
);
|
||||
$em->remove($sequenceResourceToDelete);
|
||||
}
|
||||
|
||||
if (!$vertexToFrom && !$vertexFromTo) {
|
||||
Session::write('sr_vertex', true);
|
||||
$vertexTo = $graph->getVertex($id);
|
||||
$vertexFrom = $graph->getVertex($vertexId);
|
||||
if ($vertexTo->getVerticesEdgeFrom()->count() > 1) {
|
||||
$vertexFrom->destroy();
|
||||
$sequenceResourceToDelete = $sequenceResourceRepository->findOneBy(
|
||||
[
|
||||
'resourceId' => $vertexId,
|
||||
'type' => $type,
|
||||
'sequence' => $sequence,
|
||||
]
|
||||
);
|
||||
$em->remove($sequenceResourceToDelete);
|
||||
} else {
|
||||
$vertexTo->destroy();
|
||||
$vertexFrom->destroy();
|
||||
$sequenceResourceToDelete = $sequenceResourceRepository->findOneBy(
|
||||
[
|
||||
'resourceId' => $vertexId,
|
||||
'type' => $type,
|
||||
'sequence' => $sequence,
|
||||
]
|
||||
);
|
||||
$em->remove($sequenceResource);
|
||||
$em->remove($sequenceResourceToDelete);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$sequence->setGraphAndSerialize($graph);
|
||||
$em->merge($sequence);
|
||||
$em->flush();
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case 'load_resource':
|
||||
api_block_anonymous_users();
|
||||
api_protect_admin_script();
|
||||
|
||||
// children or parent
|
||||
$loadResourceType = $_REQUEST['load_resource_type'] ?? null;
|
||||
|
||||
/** @var Sequence $sequence */
|
||||
$sequence = $sequenceRepository->find($sequenceId);
|
||||
|
||||
if (empty($sequence)) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/** @var SequenceResource $sequenceResource */
|
||||
$sequenceResource = $sequenceResourceRepository->findOneBy(
|
||||
['resourceId' => $id, 'type' => $type, 'sequence' => $sequence]
|
||||
);
|
||||
|
||||
if (null === $sequenceResource) {
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($sequenceResource->hasGraph()) {
|
||||
$graph = $sequenceResource->getSequence()->getUnSerializeGraph();
|
||||
|
||||
/** @var Vertex $mainVertice */
|
||||
if ($graph->hasVertex($id)) {
|
||||
$mainVertex = $graph->getVertex($id);
|
||||
|
||||
if (!empty($mainVertex)) {
|
||||
$vertexList = null;
|
||||
switch ($loadResourceType) {
|
||||
case 'parent':
|
||||
$vertexList = $mainVertex->getVerticesEdgeFrom();
|
||||
|
||||
break;
|
||||
case 'children':
|
||||
$vertexList = $mainVertex->getVerticesEdgeTo();
|
||||
break;
|
||||
}
|
||||
|
||||
$list = [];
|
||||
if (!empty($vertexList)) {
|
||||
foreach ($vertexList as $vertex) {
|
||||
$list[] = $vertex->getId();
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($list)) {
|
||||
echo implode(',', $list);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'save_resource':
|
||||
api_block_anonymous_users();
|
||||
api_protect_admin_script();
|
||||
|
||||
$parents = $_REQUEST['parents'] ?? '';
|
||||
|
||||
if (empty($parents) || empty($sequenceId) || empty($type)) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/** @var Sequence $sequence */
|
||||
$sequence = $sequenceRepository->find($sequenceId);
|
||||
|
||||
if (null === $sequence) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/*$vertexFromSession = Session::read('sr_vertex');
|
||||
if ($vertexFromSession) {
|
||||
Session::erase('sr_vertex');
|
||||
echo Display::return_message(get_lang('Saved'), 'success');
|
||||
break;
|
||||
}*/
|
||||
|
||||
$parents = str_replace($id, '', $parents);
|
||||
$parents = explode(',', $parents);
|
||||
$parents = array_filter($parents);
|
||||
|
||||
if ($sequence->hasGraph()) {
|
||||
$graph = $sequence->getUnSerializeGraph();
|
||||
} else {
|
||||
$graph = new Graph();
|
||||
}
|
||||
|
||||
if ($graph->hasVertex($id)) {
|
||||
$main = $graph->getVertex($id);
|
||||
} else {
|
||||
$main = $graph->createVertex($id);
|
||||
}
|
||||
|
||||
$item = $sequenceRepository->getItem($id, $type);
|
||||
$main->setAttribute('graphviz.shape', 'record');
|
||||
$main->setAttribute('graphviz.label', $item->getName());
|
||||
|
||||
foreach ($parents as $parentId) {
|
||||
$item = $sequenceRepository->getItem($parentId, $type);
|
||||
if ($graph->hasVertex($parentId)) {
|
||||
$parent = $graph->getVertex($parentId);
|
||||
if (!$parent->hasEdgeTo($main)) {
|
||||
$newEdge = $parent->createEdgeTo($main);
|
||||
}
|
||||
} else {
|
||||
$parent = $graph->createVertex($parentId);
|
||||
$newEdge = $parent->createEdgeTo($main);
|
||||
}
|
||||
|
||||
$parent->setAttribute('graphviz.shape', 'record');
|
||||
$parent->setAttribute('graphviz.label', $item->getName());
|
||||
}
|
||||
|
||||
foreach ($parents as $parentId) {
|
||||
$sequenceResourceParent = $sequenceResourceRepository->findOneBy(
|
||||
['resourceId' => $parentId, 'type' => $type, 'sequence' => $sequence]
|
||||
);
|
||||
|
||||
if (empty($sequenceResourceParent)) {
|
||||
$sequenceResourceParent = new SequenceResource();
|
||||
$sequenceResourceParent
|
||||
->setSequence($sequence)
|
||||
->setType($type)
|
||||
->setResourceId($parentId);
|
||||
$em->persist($sequenceResourceParent);
|
||||
}
|
||||
}
|
||||
|
||||
/** @var SequenceResource $sequenceResource */
|
||||
$sequenceResource = $sequenceResourceRepository->findOneBy(
|
||||
['resourceId' => $id, 'type' => $type, 'sequence' => $sequence]
|
||||
);
|
||||
|
||||
if (null === $sequenceResource) {
|
||||
// Create
|
||||
$sequence->setGraphAndSerialize($graph);
|
||||
$sequenceResource = new SequenceResource();
|
||||
$sequenceResource
|
||||
->setSequence($sequence)
|
||||
->setType($type)
|
||||
->setResourceId($id);
|
||||
} else {
|
||||
// Update
|
||||
$sequenceResource->getSequence()->setGraphAndSerialize($graph);
|
||||
}
|
||||
$em->persist($sequenceResource);
|
||||
$em->flush();
|
||||
|
||||
echo Display::return_message(get_lang('Saved'), 'success');
|
||||
|
||||
break;
|
||||
case 'get_requirements':
|
||||
case 'get_dependents':
|
||||
$sessionId = isset($_REQUEST['sid']) ? (int) $_REQUEST['sid'] : 0;
|
||||
$userId = api_get_user_id();
|
||||
$resourceName = '';
|
||||
$template = '';
|
||||
switch ($type) {
|
||||
case SequenceResource::SESSION_TYPE:
|
||||
$resourceData = api_get_session_info($id);
|
||||
|
||||
$resourceName = $resourceData['name'];
|
||||
$template = 'session_requirements.tpl';
|
||||
break;
|
||||
case SequenceResource::COURSE_TYPE:
|
||||
$resourceData = api_get_course_info_by_id($id);
|
||||
$resourceName = $resourceData['title'];
|
||||
$template = 'course_requirements.tpl';
|
||||
break;
|
||||
}
|
||||
|
||||
if (empty($resourceData) || empty($template)) {
|
||||
exit;
|
||||
}
|
||||
|
||||
if ('get_requirements' === $action) {
|
||||
$sequences = $sequenceResourceRepository->getRequirements($id, $type);
|
||||
$sequenceList = $sequenceResourceRepository->checkRequirementsForUser($sequences, $type, $userId, $sessionId);
|
||||
|
||||
$allowSubscription = $sequenceResourceRepository->checkSequenceAreCompleted($sequenceList);
|
||||
} else {
|
||||
$sequences = $sequenceResourceRepository->getDependents($id, $type);
|
||||
$sequenceList = $sequenceResourceRepository->checkDependentsForUser($sequences, $type, $userId, $sessionId);
|
||||
|
||||
$allowSubscription = $sequenceResourceRepository->checkSequenceAreCompleted(
|
||||
$sequenceList,
|
||||
SequenceResourceRepository::VERTICES_TYPE_DEP
|
||||
);
|
||||
}
|
||||
|
||||
$view = new Template(null, false, false, false, false, false);
|
||||
$view->assign('sequences', $sequenceList);
|
||||
$view->assign('sequence_type', $type);
|
||||
$view->assign('allow_subscription', $allowSubscription);
|
||||
$view->assign(
|
||||
'item_type',
|
||||
'get_requirements' === $action
|
||||
? SequenceResourceRepository::VERTICES_TYPE_REQ
|
||||
: SequenceResourceRepository::VERTICES_TYPE_DEP
|
||||
);
|
||||
$course = api_get_course_entity();
|
||||
if ($course) {
|
||||
$view->assign(
|
||||
'current_requirement_is_completed',
|
||||
$sequenceResourceRepository->checkCourseRequirements($userId, $course, $sessionId)
|
||||
);
|
||||
}
|
||||
|
||||
if ($allowSubscription) {
|
||||
$view->assign(
|
||||
'subscribe_button',
|
||||
CoursesAndSessionsCatalog::getRegisteredInSessionButton(
|
||||
$id,
|
||||
$resourceName,
|
||||
false
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$view->display($view->get_template('sequence_resource/'.$template));
|
||||
|
||||
break;
|
||||
}
|
||||
471
main/inc/ajax/session.ajax.php
Normal file
471
main/inc/ajax/session.ajax.php
Normal file
@@ -0,0 +1,471 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use Chamilo\UserBundle\Entity\User;
|
||||
|
||||
/**
|
||||
* Responses to AJAX calls.
|
||||
*/
|
||||
require_once __DIR__.'/../global.inc.php';
|
||||
|
||||
$action = $_REQUEST['a'];
|
||||
|
||||
switch ($action) {
|
||||
case 'get_user_sessions':
|
||||
if (api_is_platform_admin() || api_is_session_admin()) {
|
||||
$user_id = (int) $_POST['user_id'];
|
||||
$list_sessions = SessionManager::get_sessions_by_user($user_id, true);
|
||||
if (!empty($list_sessions)) {
|
||||
foreach ($list_sessions as $session_item) {
|
||||
echo $session_item['session_name'].'<br />';
|
||||
}
|
||||
} else {
|
||||
echo get_lang('NoSessionsForThisUser');
|
||||
}
|
||||
unset($list_sessions);
|
||||
}
|
||||
break;
|
||||
case 'order':
|
||||
api_protect_admin_script();
|
||||
$allowOrder = api_get_configuration_value('session_list_order');
|
||||
if ($allowOrder) {
|
||||
$order = isset($_GET['order']) ? $_GET['order'] : [];
|
||||
$order = json_decode($order);
|
||||
if (!empty($order)) {
|
||||
$table = Database::get_main_table(TABLE_MAIN_SESSION);
|
||||
foreach ($order as $data) {
|
||||
if (isset($data->order) && isset($data->id)) {
|
||||
$orderId = (int) $data->order;
|
||||
$sessionId = (int) $data->id;
|
||||
$sql = "UPDATE $table SET position = $orderId WHERE id = $sessionId ";
|
||||
Database::query($sql);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'search_session':
|
||||
if (api_is_platform_admin()) {
|
||||
$sessions = SessionManager::get_sessions_list(
|
||||
[
|
||||
's.name' => [
|
||||
'operator' => 'LIKE',
|
||||
'value' => "%".$_REQUEST['q']."%",
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$list = [
|
||||
'items' => [],
|
||||
];
|
||||
|
||||
if (empty($sessions)) {
|
||||
echo json_encode([]);
|
||||
break;
|
||||
}
|
||||
|
||||
foreach ($sessions as $session) {
|
||||
$list['items'][] = [
|
||||
'id' => $session['id'],
|
||||
'text' => $session['name'],
|
||||
];
|
||||
}
|
||||
|
||||
echo json_encode($list);
|
||||
}
|
||||
break;
|
||||
case 'search_session_all':
|
||||
if (api_is_platform_admin()) {
|
||||
$results = SessionManager::get_sessions_list(
|
||||
[
|
||||
's.name' => ['operator' => 'like', 'value' => "%".$_REQUEST['q']."%"],
|
||||
'c.id' => ['operator' => '=', 'value' => $_REQUEST['course_id']],
|
||||
]
|
||||
);
|
||||
$results2 = [];
|
||||
if (!empty($results)) {
|
||||
foreach ($results as $item) {
|
||||
$item2 = [];
|
||||
foreach ($item as $id => $internal) {
|
||||
if ($id == 'id') {
|
||||
$item2[$id] = $internal;
|
||||
}
|
||||
if ($id == 'name') {
|
||||
$item2['text'] = $internal;
|
||||
}
|
||||
}
|
||||
$results2[] = $item2;
|
||||
}
|
||||
$results2[] = ['T', 'text' => 'TODOS', 'id' => 'T'];
|
||||
echo json_encode($results2);
|
||||
} else {
|
||||
echo json_encode([['T', 'text' => 'TODOS', 'id' => 'T']]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'search_session_by_course':
|
||||
if (api_is_platform_admin()) {
|
||||
$results = SessionManager::get_sessions_list(
|
||||
[
|
||||
's.name' => ['operator' => 'like', 'value' => "%".$_REQUEST['q']."%"],
|
||||
'c.id' => ['operator' => '=', 'value' => $_REQUEST['course_id']],
|
||||
]
|
||||
);
|
||||
$json = [
|
||||
'items' => [
|
||||
['id' => 'T', 'text' => get_lang('All')],
|
||||
],
|
||||
];
|
||||
if (!empty($results)) {
|
||||
foreach ($results as $item) {
|
||||
$item2 = [];
|
||||
foreach ($item as $id => $internal) {
|
||||
if ($id == 'id') {
|
||||
$item2[$id] = $internal;
|
||||
}
|
||||
if ($id == 'name') {
|
||||
$item2['text'] = $internal;
|
||||
}
|
||||
}
|
||||
$json['items'][] = $item2;
|
||||
}
|
||||
}
|
||||
|
||||
echo json_encode($json);
|
||||
}
|
||||
break;
|
||||
case 'session_info':
|
||||
$sessionId = isset($_GET['session_id']) ? $_GET['session_id'] : '';
|
||||
$sessionInfo = api_get_session_info($sessionId);
|
||||
|
||||
$extraFieldValues = new ExtraFieldValue('session');
|
||||
$extraField = new ExtraField('session');
|
||||
$values = $extraFieldValues->getAllValuesByItem($sessionId);
|
||||
$load = isset($_GET['load_empty_extra_fields']) ? true : false;
|
||||
|
||||
if ($load) {
|
||||
$allExtraFields = $extraField->get_all();
|
||||
$valueList = array_column($values, 'id');
|
||||
foreach ($allExtraFields as $extra) {
|
||||
if (!in_array($extra['id'], $valueList)) {
|
||||
$values[] = [
|
||||
'id' => $extra['id'],
|
||||
'variable' => $extra['variable'],
|
||||
'value' => '',
|
||||
'field_type' => $extra['field_type'],
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$sessionInfo['extra_fields'] = $values;
|
||||
|
||||
if (!empty($sessionInfo)) {
|
||||
echo json_encode($sessionInfo);
|
||||
}
|
||||
break;
|
||||
case 'get_description':
|
||||
if (isset($_GET['session'])) {
|
||||
$sessionInfo = api_get_session_info($_GET['session']);
|
||||
echo '<h2>'.$sessionInfo['name'].'</h2>';
|
||||
echo '<div class="home-course-intro"><div class="page-course"><div class="page-course-intro">';
|
||||
echo $sessionInfo['show_description'] == 1 ? $sessionInfo['description'] : get_lang('None');
|
||||
echo '</div></div></div>';
|
||||
}
|
||||
break;
|
||||
case 'search_general_coach':
|
||||
SessionManager::protectSession(null, false);
|
||||
api_protect_limit_for_session_admin();
|
||||
|
||||
if (api_is_anonymous()) {
|
||||
echo '';
|
||||
break;
|
||||
}
|
||||
|
||||
$list = [
|
||||
'items' => [],
|
||||
];
|
||||
|
||||
$usersRepo = UserManager::getRepository();
|
||||
$users = $usersRepo->searchUsersByStatus($_GET['q'], COURSEMANAGER, api_get_current_access_url_id());
|
||||
/** @var User $user */
|
||||
foreach ($users as $user) {
|
||||
$list['items'][] = [
|
||||
'id' => $user->getId(),
|
||||
'text' => UserManager::formatUserFullName($user),
|
||||
];
|
||||
}
|
||||
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode($list);
|
||||
break;
|
||||
case 'get_courses_inside_session':
|
||||
$userId = api_get_user_id();
|
||||
$isAdmin = api_is_platform_admin();
|
||||
if ($isAdmin) {
|
||||
$sessionList = SessionManager::get_sessions_list();
|
||||
$sessionIdList = array_column($sessionList, 'id');
|
||||
} else {
|
||||
$sessionList = SessionManager::get_sessions_by_user($userId);
|
||||
$sessionIdList = array_column($sessionList, 'session_id');
|
||||
}
|
||||
|
||||
$sessionId = isset($_GET['session_id']) ? (int) $_GET['session_id'] : 0;
|
||||
$courseList = [];
|
||||
if (empty($sessionId)) {
|
||||
$preCourseList = CourseManager::get_courses_list_by_user_id(
|
||||
$userId,
|
||||
false,
|
||||
true
|
||||
);
|
||||
$courseList = array_column($preCourseList, 'real_id');
|
||||
} else {
|
||||
if ($isAdmin) {
|
||||
$courseList = SessionManager::getCoursesInSession($sessionId);
|
||||
} else {
|
||||
if (in_array($sessionId, $sessionIdList)) {
|
||||
$courseList = SessionManager::getCoursesInSession($sessionId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$courseListToSelect = [];
|
||||
if (!empty($courseList)) {
|
||||
// Course List
|
||||
foreach ($courseList as $courseId) {
|
||||
$courseInfo = api_get_course_info_by_id($courseId);
|
||||
$courseListToSelect[] = [
|
||||
'id' => $courseInfo['real_id'],
|
||||
'name' => $courseInfo['title'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
echo json_encode($courseListToSelect);
|
||||
break;
|
||||
case 'get_basic_course_documents_list':
|
||||
case 'get_basic_course_documents_form':
|
||||
$courseId = isset($_GET['course']) ? (int) $_GET['course'] : 0;
|
||||
$sessionId = isset($_GET['session']) ? (int) $_GET['session'] : 0;
|
||||
$currentUserId = api_get_user_id();
|
||||
|
||||
$em = Database::getManager();
|
||||
|
||||
$course = $em->find('ChamiloCoreBundle:Course', $courseId);
|
||||
$session = $em->find('ChamiloCoreBundle:Session', $sessionId);
|
||||
|
||||
if (!$course || !$session) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!api_is_platform_admin(true) || $session->getSessionAdminId() != $currentUserId) {
|
||||
break;
|
||||
}
|
||||
|
||||
$folderName = '/basic-course-documents__'.$session->getId().'__0';
|
||||
|
||||
if ('get_basic_course_documents_list' === $action) {
|
||||
$courseInfo = api_get_course_info_by_id($course->getId());
|
||||
$exists = DocumentManager::folderExists('/basic-course-documents', $courseInfo, $session->getId(), 0);
|
||||
if (!$exists) {
|
||||
$courseDir = $courseInfo['directory'].'/document';
|
||||
$baseWorkDir = api_get_path(SYS_COURSE_PATH).$courseDir;
|
||||
|
||||
$newFolderData = create_unexisting_directory(
|
||||
$courseInfo,
|
||||
$currentUserId,
|
||||
$session->getId(),
|
||||
0,
|
||||
0,
|
||||
$baseWorkDir,
|
||||
'/basic-course-documents',
|
||||
get_lang('BasicCourseDocuments'),
|
||||
1
|
||||
);
|
||||
|
||||
$id = (int) $newFolderData['iid'];
|
||||
} else {
|
||||
$id = DocumentManager::get_document_id($courseInfo, $folderName, $session->getId());
|
||||
}
|
||||
$http_www = api_get_path(WEB_COURSE_PATH).$courseInfo['directory'].'/document';
|
||||
|
||||
$documentAndFolders = DocumentManager::getAllDocumentData(
|
||||
$courseInfo,
|
||||
$folderName,
|
||||
0,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
$session->getId()
|
||||
);
|
||||
|
||||
$documentAndFolders = array_filter(
|
||||
$documentAndFolders,
|
||||
function (array $documentData) {
|
||||
return $documentData['filetype'] != 'folder';
|
||||
}
|
||||
);
|
||||
$documentAndFolders = array_map(
|
||||
function (array $documentData) use ($course, $session, $folderName) {
|
||||
$downloadUrl = api_get_path(WEB_CODE_PATH).'document/document.php?'
|
||||
.api_get_cidreq_params($course->getCode(), $session->getId()).'&'
|
||||
.http_build_query(['action' => 'download', 'id' => $documentData['id']]);
|
||||
$deleteUrl = api_get_path(WEB_AJAX_PATH).'session.ajax.php?'
|
||||
.http_build_query(
|
||||
[
|
||||
'a' => 'delete_basic_course_documents',
|
||||
'deleteid' => $documentData['id'],
|
||||
'curdirpath' => $folderName,
|
||||
'course' => $course->getId(),
|
||||
'session' => $session->getId(),
|
||||
]
|
||||
);
|
||||
|
||||
$row = [];
|
||||
$row[] = DocumentManager::build_document_icon_tag($documentData['filetype'], $documentData['path']);
|
||||
$row[] = Display::url($documentData['title'], $downloadUrl);
|
||||
$row[] = format_file_size($documentData['size']);
|
||||
$row[] = date_to_str_ago($documentData['lastedit_date']).PHP_EOL
|
||||
.'<div class="muted"><small>'
|
||||
.api_get_local_time($documentData['lastedit_date'])
|
||||
."</small></div>";
|
||||
|
||||
$row[] = Display::url(
|
||||
Display::return_icon('save.png', get_lang('Download')),
|
||||
$downloadUrl
|
||||
)
|
||||
.PHP_EOL
|
||||
.Display::url(
|
||||
Display::return_icon('delete.png', get_lang('Delete')),
|
||||
$deleteUrl,
|
||||
[
|
||||
'class' => 'delete_document',
|
||||
'data-course' => $course->getId(),
|
||||
'data-session' => $session->getId(),
|
||||
]
|
||||
);
|
||||
|
||||
return $row;
|
||||
},
|
||||
$documentAndFolders
|
||||
);
|
||||
|
||||
$table = new SortableTableFromArray($documentAndFolders, 1, 20, $folderName);
|
||||
$table->set_header(0, get_lang('Type'), false, [], ['class' => 'text-center', 'width' => '60px']);
|
||||
$table->set_header(1, get_lang('Name'), false);
|
||||
$table->set_header(2, get_lang('Size'), false, [], ['class' => 'text-right', 'style' => 'width: 80px;']);
|
||||
$table->set_header(3, get_lang('Date'), false, [], ['class' => 'text-center', 'style' => 'width: 200px;']);
|
||||
$table->set_header(4, get_lang('Actions'), false, [], ['class' => 'text-center']);
|
||||
$table->display();
|
||||
}
|
||||
|
||||
if ('get_basic_course_documents_form' === $action) {
|
||||
$form = new FormValidator('get_basic_course_documents_form_'.$session->getId());
|
||||
$form->addMultipleUpload(
|
||||
api_get_path(WEB_AJAX_PATH).'document.ajax.php?'
|
||||
.api_get_cidreq_params($course->getCode(), $session->getId())
|
||||
.'&a=upload_file&curdirpath='.$folderName,
|
||||
''
|
||||
);
|
||||
|
||||
$form->display();
|
||||
}
|
||||
break;
|
||||
case 'delete_basic_course_documents':
|
||||
$curdirpath = isset($_GET['curdirpath']) ? Security::remove_XSS($_GET['curdirpath']) : null;
|
||||
$docId = isset($_GET['deleteid']) ? (int) $_GET['deleteid'] : 0;
|
||||
$courseId = isset($_GET['course']) ? (int) $_GET['course'] : 0;
|
||||
$sessionId = isset($_GET['session']) ? (int) $_GET['session'] : 0;
|
||||
|
||||
if (empty($curdirpath) || empty($docId) || empty($courseId) || empty($sessionId)) {
|
||||
break;
|
||||
}
|
||||
|
||||
$em = Database::getManager();
|
||||
|
||||
$courseInfo = api_get_course_info_by_id($courseId);
|
||||
$session = $em->find('ChamiloCoreBundle:Session', $sessionId);
|
||||
$currentUserId = api_get_user_id();
|
||||
|
||||
if (empty($courseInfo) || !$session) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!api_is_platform_admin(true) || $session->getSessionAdminId() != $currentUserId) {
|
||||
break;
|
||||
}
|
||||
|
||||
$sysCoursePath = api_get_path(SYS_COURSE_PATH);
|
||||
$courseDir = $courseInfo['directory'].'/document';
|
||||
$baseWorkDir = $sysCoursePath.$courseDir;
|
||||
|
||||
$documentInfo = DocumentManager::get_document_data_by_id(
|
||||
$docId,
|
||||
$courseInfo['code'],
|
||||
false,
|
||||
$session->getId()
|
||||
);
|
||||
|
||||
if (empty($documentInfo)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ($documentInfo['filetype'] != 'link') {
|
||||
$deletedDocument = DocumentManager::delete_document(
|
||||
$courseInfo,
|
||||
null,
|
||||
$baseWorkDir,
|
||||
$session->getId(),
|
||||
$docId
|
||||
);
|
||||
} else {
|
||||
$deletedDocument = DocumentManager::deleteCloudLink(
|
||||
$courseInfo,
|
||||
$docId
|
||||
);
|
||||
}
|
||||
|
||||
if (!$deletedDocument) {
|
||||
break;
|
||||
}
|
||||
|
||||
echo true;
|
||||
break;
|
||||
case 'search_template_session':
|
||||
SessionManager::protectSession(null, false);
|
||||
|
||||
api_protect_limit_for_session_admin();
|
||||
|
||||
if (empty($_GET['q'])) {
|
||||
break;
|
||||
}
|
||||
|
||||
$q = strtolower(trim($_GET['q']));
|
||||
|
||||
$list = array_map(
|
||||
function ($session) {
|
||||
return [
|
||||
'id' => $session['id'],
|
||||
'text' => strip_tags($session['name']),
|
||||
];
|
||||
},
|
||||
SessionManager::formatSessionsAdminForGrid()
|
||||
);
|
||||
|
||||
$list = array_filter(
|
||||
$list,
|
||||
function ($session) use ($q) {
|
||||
$name = strtolower($session['text']);
|
||||
|
||||
return strpos($name, $q) !== false;
|
||||
}
|
||||
);
|
||||
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode(['items' => array_values($list)]);
|
||||
break;
|
||||
default:
|
||||
echo '';
|
||||
}
|
||||
exit;
|
||||
74
main/inc/ajax/session_clock.ajax.php
Normal file
74
main/inc/ajax/session_clock.ajax.php
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__.'/../../../vendor/autoload.php';
|
||||
require_once __DIR__.'/../../../app/AppKernel.php';
|
||||
|
||||
$kernel = new AppKernel('', '');
|
||||
|
||||
// Check for 'action' parameter in the GET request
|
||||
if (isset($_GET['action'])) {
|
||||
$action = $_GET['action'];
|
||||
|
||||
if ($action == 'time') {
|
||||
// Load the Chamilo configuration
|
||||
$alreadyInstalled = false;
|
||||
if (file_exists($kernel->getConfigurationFile())) {
|
||||
require_once $kernel->getConfigurationFile();
|
||||
$alreadyInstalled = true;
|
||||
}
|
||||
|
||||
// Load the API library BEFORE loading the Chamilo configuration
|
||||
require_once $_configuration['root_sys'].'main/inc/lib/api.lib.php';
|
||||
|
||||
if (api_get_configuration_value('session_lifetime_controller')) {
|
||||
// Get the session
|
||||
session_name('ch_sid');
|
||||
session_start();
|
||||
|
||||
$session = new ChamiloSession();
|
||||
|
||||
$endTime = 0;
|
||||
$isExpired = false;
|
||||
$timeLeft = -1;
|
||||
|
||||
$currentTime = time();
|
||||
|
||||
// Existing code for time action
|
||||
if ($alreadyInstalled && api_get_user_id()) {
|
||||
$endTime = $session->end_time();
|
||||
$isExpired = $session->is_expired();
|
||||
} else {
|
||||
// Chamilo not installed or user not logged in
|
||||
$endTime = $currentTime + 315360000; // This sets a default end time far in the future
|
||||
$isExpired = false;
|
||||
}
|
||||
|
||||
$timeLeft = $endTime - $currentTime;
|
||||
} else {
|
||||
$endTime = 999999;
|
||||
$isExpired = false;
|
||||
$timeLeft = 999999;
|
||||
}
|
||||
|
||||
if ($endTime > 0) {
|
||||
echo json_encode(['sessionEndDate' => $endTime, 'sessionTimeLeft' => $timeLeft, 'sessionExpired' => $isExpired]);
|
||||
} else {
|
||||
http_response_code(500);
|
||||
echo json_encode(['error' => 'Error retrieving data from the current session']);
|
||||
}
|
||||
} elseif ($action == 'logout') {
|
||||
require_once __DIR__.'/../../../main/inc/global-min.inc.php';
|
||||
|
||||
$userId = api_get_user_id();
|
||||
online_logout($userId, false);
|
||||
echo json_encode(['message' => 'Logged out successfully']);
|
||||
} else {
|
||||
// Handle unexpected action value
|
||||
http_response_code(400);
|
||||
echo json_encode(['error' => 'Invalid action parameter']);
|
||||
}
|
||||
} else {
|
||||
// No action provided
|
||||
http_response_code(400);
|
||||
echo json_encode(['error' => 'No action parameter provided']);
|
||||
}
|
||||
530
main/inc/ajax/skill.ajax.php
Normal file
530
main/inc/ajax/skill.ajax.php
Normal file
@@ -0,0 +1,530 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Responses to AJAX calls.
|
||||
*/
|
||||
|
||||
use Chamilo\SkillBundle\Entity\SkillRelCourse;
|
||||
use Chamilo\SkillBundle\Entity\SkillRelItem;
|
||||
|
||||
require_once __DIR__.'/../global.inc.php';
|
||||
|
||||
$action = $_REQUEST['a'] ?? null;
|
||||
|
||||
api_block_anonymous_users();
|
||||
|
||||
Skill::isAllowed(api_get_user_id());
|
||||
|
||||
$skill = new Skill();
|
||||
$gradebook = new Gradebook();
|
||||
$skillGradeBook = new SkillRelGradebook();
|
||||
$userId = api_get_user_id();
|
||||
|
||||
switch ($action) {
|
||||
case 'add':
|
||||
if (api_is_platform_admin() || api_is_drh()) {
|
||||
if (!empty($_REQUEST['id'])) {
|
||||
$skillId = $skill->edit($_REQUEST);
|
||||
} else {
|
||||
$skillId = $skill->add($_REQUEST);
|
||||
}
|
||||
}
|
||||
echo $skillId;
|
||||
break;
|
||||
case 'delete_skill':
|
||||
if (api_is_platform_admin() || api_is_drh()) {
|
||||
echo $skill->delete($_REQUEST['skill_id']);
|
||||
}
|
||||
break;
|
||||
case 'find_skills':
|
||||
$returnSkills = [[
|
||||
'items' => [],
|
||||
]];
|
||||
|
||||
if (!empty($_REQUEST['q'])) {
|
||||
$skills = $skill->find('all', ['where' => ['name LIKE %?% ' => $_REQUEST['q']]]);
|
||||
foreach ($skills as $skill) {
|
||||
$returnSkills['items'][] = [
|
||||
'id' => $skill['id'],
|
||||
'text' => $skill['name'],
|
||||
];
|
||||
}
|
||||
}
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode($returnSkills);
|
||||
break;
|
||||
case 'get_gradebooks':
|
||||
$gradebooks = $gradebook_list = $gradebook->get_all();
|
||||
$gradebook_list = [];
|
||||
//Only course gradebook with certificate
|
||||
if (!empty($gradebooks)) {
|
||||
foreach ($gradebooks as $gradebook) {
|
||||
if ($gradebook['parent_id'] == 0 &&
|
||||
!empty($gradebook['certif_min_score']) &&
|
||||
!empty($gradebook['document_id'])
|
||||
) {
|
||||
$gradebook_list[] = $gradebook;
|
||||
}
|
||||
}
|
||||
}
|
||||
echo json_encode($gradebook_list);
|
||||
break;
|
||||
case 'find_gradebooks':
|
||||
$return = [];
|
||||
if (!empty($_REQUEST['tag'])) {
|
||||
$gradebooks = $gradebook->find('all', ['where' => ['name LIKE %?% ' => $_REQUEST['tag']]]);
|
||||
foreach ($gradebooks as $item) {
|
||||
$item['key'] = $item['name'];
|
||||
$item['value'] = $item['id'];
|
||||
$return[] = $item;
|
||||
}
|
||||
}
|
||||
echo json_encode($return);
|
||||
break;
|
||||
case 'get_course_info_popup':
|
||||
$courseInfo = api_get_course_info($_REQUEST['code']);
|
||||
$courses = CourseManager::processHotCourseItem(
|
||||
[
|
||||
['c_id' => $courseInfo['real_id']],
|
||||
]
|
||||
);
|
||||
Display::display_no_header();
|
||||
Display::$global_template->assign('hot_courses', $courses);
|
||||
$template = Display::$global_template->get_template('layout/hot_course_item_popup.tpl');
|
||||
echo Display::$global_template->fetch($template);
|
||||
break;
|
||||
case 'gradebook_exists':
|
||||
$data = $gradebook->get($_REQUEST['gradebook_id']);
|
||||
if (!empty($data)) {
|
||||
echo 1;
|
||||
} else {
|
||||
echo 0;
|
||||
}
|
||||
break;
|
||||
case 'get_skills_by_profile':
|
||||
$skillRelProfile = new SkillRelProfile();
|
||||
$profile_id = $_REQUEST['profile_id'] ?? null;
|
||||
$skills = $skillRelProfile->getSkillsByProfile($profile_id);
|
||||
echo json_encode($skills);
|
||||
break;
|
||||
case 'get_saved_profiles':
|
||||
$skillProfile = new SkillProfile();
|
||||
$profiles = $skillProfile->get_all();
|
||||
Display::display_no_header();
|
||||
Display::$global_template->assign('profiles', $profiles);
|
||||
$template = Display::$global_template->get_template('skill/profile_item.tpl');
|
||||
echo Display::$global_template->fetch($template);
|
||||
break;
|
||||
case 'get_skills':
|
||||
$loadUserData = $_REQUEST['load_user_data'] ?? null;
|
||||
$id = intval($_REQUEST['id']);
|
||||
$skills = $skill->get_all($loadUserData, false, $id);
|
||||
echo json_encode($skills);
|
||||
break;
|
||||
case 'get_skill_info':
|
||||
$id = $_REQUEST['id'] ?? null;
|
||||
$skillInfo = $skill->getSkillInfo($id);
|
||||
echo json_encode($skillInfo);
|
||||
break;
|
||||
case 'get_skill_course_info':
|
||||
$id = $_REQUEST['id'] ?? null;
|
||||
$skillInfo = $skill->getSkillInfo($id);
|
||||
$courses = $skill->getCoursesBySkill($id);
|
||||
$sessions = $skill->getSessionsBySkill($id);
|
||||
$html = '';
|
||||
if (!empty($courses) || !empty($sessions)) {
|
||||
Display::display_no_header();
|
||||
Display::$global_template->assign('skill', $skillInfo);
|
||||
Display::$global_template->assign('courses', $courses);
|
||||
Display::$global_template->assign('sessions', $sessions);
|
||||
$template = Display::$global_template->get_template('skill/skill_info.tpl');
|
||||
$html = Display::$global_template->fetch($template);
|
||||
}
|
||||
echo $html;
|
||||
break;
|
||||
case 'get_skills_tree_json':
|
||||
header('Content-Type: application/json');
|
||||
$userId = isset($_REQUEST['load_user']) && $_REQUEST['load_user'] == 1 ? api_get_user_id() : 0;
|
||||
$skill_id = isset($_REQUEST['skill_id']) ? intval($_REQUEST['skill_id']) : 0;
|
||||
$depth = isset($_REQUEST['main_depth']) ? intval($_REQUEST['main_depth']) : 2;
|
||||
$all = $skill->getSkillsTreeToJson($userId, $skill_id, false, $depth);
|
||||
echo $all;
|
||||
break;
|
||||
case 'get_user_skill':
|
||||
$skillId = isset($_REQUEST['profile_id']) ? intval($_REQUEST['profile_id']) : 0;
|
||||
$skill = $skill->userHasSkill($userId, $skillId);
|
||||
if ($skill) {
|
||||
echo 1;
|
||||
} else {
|
||||
echo 0;
|
||||
}
|
||||
break;
|
||||
case 'get_all_user_skills':
|
||||
if (strpos($_SERVER['HTTP_REFERER'], "/main/admin/skills_wheel.php") !== false) {
|
||||
$userId = 0;
|
||||
}
|
||||
$skills = $skill->getUserSkills($userId, true);
|
||||
echo json_encode($skills);
|
||||
break;
|
||||
case 'get_user_skills':
|
||||
$skills = $skill->getUserSkills($userId, true);
|
||||
Display::display_no_header();
|
||||
Display::$global_template->assign('skills', $skills);
|
||||
$template = Display::$global_template->get_template('skill/user_skills.tpl');
|
||||
echo Display::$global_template->fetch($template);
|
||||
break;
|
||||
case 'get_gradebook_info':
|
||||
$id = isset($_REQUEST['id']) ? intval($_REQUEST['id']) : null;
|
||||
$info = $gradebook->get($id);
|
||||
echo json_encode($info);
|
||||
break;
|
||||
case 'load_children':
|
||||
$id = isset($_REQUEST['id']) ? intval($_REQUEST['id']) : null;
|
||||
$load_user_data = $_REQUEST['load_user_data'] ?? null;
|
||||
$skills = $skill->getChildren($id, $load_user_data);
|
||||
$return = [];
|
||||
foreach ($skills as $skill) {
|
||||
if (!empty($skill['data'])) {
|
||||
$return[$skill['data']['id']] = [
|
||||
'id' => $skill['data']['id'],
|
||||
'name' => $skill['data']['name'],
|
||||
'passed' => $skill['data']['passed'],
|
||||
];
|
||||
}
|
||||
}
|
||||
$success = true;
|
||||
if (empty($return)) {
|
||||
$success = false;
|
||||
}
|
||||
|
||||
$result = [
|
||||
'success' => $success,
|
||||
'data' => $return,
|
||||
];
|
||||
echo json_encode($result);
|
||||
break;
|
||||
case 'load_direct_parents':
|
||||
$id = isset($_REQUEST['id']) ? intval($_REQUEST['id']) : null;
|
||||
$skills = $skill->getDirectParents($id);
|
||||
$return = [];
|
||||
foreach ($skills as $skill) {
|
||||
$return[$skill['data']['id']] = [
|
||||
'id' => $skill['data']['id'],
|
||||
'parent_id' => $skill['data']['parent_id'],
|
||||
'name' => $skill['data']['name'],
|
||||
];
|
||||
}
|
||||
echo json_encode($return);
|
||||
break;
|
||||
case 'profile_matches':
|
||||
$skill_rel_user = new SkillRelUser();
|
||||
$skills = !empty($_REQUEST['skill_id']) ? $_REQUEST['skill_id'] : [];
|
||||
$total_skills_to_search = $skills;
|
||||
$users = $skill_rel_user->getUserBySkills($skills);
|
||||
$user_list = [];
|
||||
$count_skills = count($skills);
|
||||
$ordered_user_list = null;
|
||||
|
||||
if (!empty($users)) {
|
||||
foreach ($users as $user) {
|
||||
$user_info = api_get_user_info($user['user_id']);
|
||||
$user_list[$user['user_id']]['user'] = $user_info;
|
||||
$my_user_skills = $skill_rel_user->getUserSkills($user['user_id']);
|
||||
$user_skill_list = [];
|
||||
foreach ($my_user_skills as $skill_item) {
|
||||
$user_skill_list[] = $skill_item['skill_id'];
|
||||
}
|
||||
|
||||
$user_skills = [];
|
||||
$found_counts = 0;
|
||||
|
||||
foreach ($skills as $skill_id) {
|
||||
$found = false;
|
||||
if (in_array($skill_id, $user_skill_list)) {
|
||||
$found = true;
|
||||
$found_counts++;
|
||||
$user_skills[$skill_id] = ['skill_id' => $skill_id, 'found' => $found];
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($my_user_skills as $my_skill) {
|
||||
if (!isset($user_skills[$my_skill['skill_id']])) {
|
||||
$user_skills[$my_skill['skill_id']] = [
|
||||
'skill_id' => $my_skill['skill_id'],
|
||||
'found' => false,
|
||||
];
|
||||
}
|
||||
$total_skills_to_search[$my_skill['skill_id']] = $my_skill['skill_id'];
|
||||
}
|
||||
$user_list[$user['user_id']]['skills'] = $user_skills;
|
||||
$user_list[$user['user_id']]['total_found_skills'] = $found_counts;
|
||||
}
|
||||
|
||||
foreach ($user_list as $user_id => $user_data) {
|
||||
$ordered_user_list[$user_data['total_found_skills']][] = $user_data;
|
||||
}
|
||||
|
||||
if (!empty($ordered_user_list)) {
|
||||
krsort($ordered_user_list);
|
||||
}
|
||||
}
|
||||
|
||||
Display::display_no_header();
|
||||
Display::$global_template->assign('order_user_list', $ordered_user_list);
|
||||
Display::$global_template->assign('total_search_skills', $count_skills);
|
||||
|
||||
$skill_list = [];
|
||||
if (!empty($total_skills_to_search)) {
|
||||
$total_skills_to_search = $skill->getSkillsInfo($total_skills_to_search);
|
||||
foreach ($total_skills_to_search as $skill_info) {
|
||||
$skill_list[$skill_info['id']] = $skill_info;
|
||||
}
|
||||
}
|
||||
|
||||
Display::$global_template->assign('skill_list', $skill_list);
|
||||
$template = Display::$global_template->get_template('skill/profile.tpl');
|
||||
echo Display::$global_template->fetch($template);
|
||||
break;
|
||||
case 'delete_gradebook_from_skill':
|
||||
case 'remove_skill':
|
||||
if (api_is_platform_admin() || api_is_drh()) {
|
||||
if (!empty($_REQUEST['skill_id']) && !empty($_REQUEST['gradebook_id'])) {
|
||||
$skill_item = $skillGradeBook->getSkillInfo(
|
||||
$_REQUEST['skill_id'],
|
||||
$_REQUEST['gradebook_id']
|
||||
);
|
||||
if (!empty($skill_item)) {
|
||||
$skillGradeBook->delete($skill_item['id']);
|
||||
echo 1;
|
||||
} else {
|
||||
echo 0;
|
||||
}
|
||||
} else {
|
||||
echo 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'get_profile':
|
||||
$skillRelProfile = new SkillRelProfile();
|
||||
$profileId = isset($_REQUEST['profile_id']) ? intval($_REQUEST['profile_id']) : null;
|
||||
$profile = $skillRelProfile->getProfileInfo($profileId);
|
||||
echo json_encode($profile);
|
||||
break;
|
||||
case 'save_profile':
|
||||
if (api_is_platform_admin() || api_is_drh()) {
|
||||
$skill_profile = new SkillProfile();
|
||||
$params = $_REQUEST;
|
||||
$params['skills'] = $params['skill_id'] ?? null;
|
||||
$profileId = isset($_REQUEST['profile']) ? intval($_REQUEST['profile']) : null;
|
||||
if ($profileId > 0) {
|
||||
$skill_profile->updateProfileInfo(
|
||||
$profileId,
|
||||
$params['name'],
|
||||
$params['description']
|
||||
);
|
||||
$skill_data = 1;
|
||||
} else {
|
||||
$skill_data = $skill_profile->save($params);
|
||||
}
|
||||
if (!empty($skill_data)) {
|
||||
echo 1;
|
||||
} else {
|
||||
echo 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'delete_profile':
|
||||
if (api_is_platform_admin() || api_is_drh()) {
|
||||
$profileId = $_REQUEST['profile'];
|
||||
$skillProfile = new SkillProfile();
|
||||
$isDeleted = $skillProfile->delete($profileId);
|
||||
|
||||
echo json_encode([
|
||||
'status' => $isDeleted,
|
||||
]);
|
||||
}
|
||||
break;
|
||||
case 'skill_exists':
|
||||
$skill_data = $skill->get($_REQUEST['skill_id']);
|
||||
if (!empty($skill_data)) {
|
||||
echo 1;
|
||||
} else {
|
||||
echo 0;
|
||||
}
|
||||
break;
|
||||
case 'search_skills':
|
||||
$returnSkills = [];
|
||||
if (!empty($_REQUEST['q'])) {
|
||||
$skills = $skill->find(
|
||||
'all',
|
||||
[
|
||||
'where' => ['name LIKE %?% ' => $_REQUEST['q']],
|
||||
]
|
||||
);
|
||||
foreach ($skills as $skill) {
|
||||
$returnSkills[] = [
|
||||
'id' => $skill['id'],
|
||||
'text' => $skill['name'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
echo json_encode(['items' => $returnSkills]);
|
||||
break;
|
||||
case 'search_skills_in_course':
|
||||
$courseId = isset($_REQUEST['course_id']) ? (int) $_REQUEST['course_id'] : 0;
|
||||
$sessionId = isset($_REQUEST['session_id']) ? (int) $_REQUEST['session_id'] : null;
|
||||
|
||||
if (empty($courseId)) {
|
||||
exit;
|
||||
}
|
||||
$em = Database::getManager();
|
||||
$skills = $em->getRepository('ChamiloSkillBundle:SkillRelCourse')->findBy(
|
||||
['course' => $courseId, 'session' => $sessionId]
|
||||
);
|
||||
|
||||
$returnSkills = [];
|
||||
/** @var SkillRelCourse $skill */
|
||||
foreach ($skills as $skill) {
|
||||
$returnSkills[] = [
|
||||
'id' => $skill->getSkill()->getId(),
|
||||
'text' => $skill->getSkill()->getName(),
|
||||
];
|
||||
}
|
||||
echo json_encode([
|
||||
'items' => $returnSkills,
|
||||
]);
|
||||
break;
|
||||
case 'update_skill_rel_user':
|
||||
$allowSkillInTools = api_get_configuration_value('allow_skill_rel_items');
|
||||
if (empty($allowSkillInTools)) {
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!api_is_allowed_to_edit()) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$creatorId = api_get_user_id();
|
||||
$typeId = isset($_REQUEST['type_id']) ? (int) $_REQUEST['type_id'] : 0;
|
||||
$itemId = isset($_REQUEST['item_id']) ? (int) $_REQUEST['item_id'] : 0;
|
||||
$skillId = isset($_REQUEST['skill_id']) ? (int) $_REQUEST['skill_id'] : 0;
|
||||
$userId = isset($_REQUEST['user_id']) ? (int) $_REQUEST['user_id'] : 0;
|
||||
$courseId = isset($_REQUEST['course_id']) ? (int) $_REQUEST['course_id'] : 0;
|
||||
$sessionId = isset($_REQUEST['session_id']) ? (int) $_REQUEST['session_id'] : 0;
|
||||
$resultId = isset($_REQUEST['result_id']) ? (int) $_REQUEST['result_id'] : 0;
|
||||
|
||||
if (!empty($typeId) && !empty($itemId) && !empty($skillId) && !empty($userId) && !empty($courseId)) {
|
||||
$em = Database::getManager();
|
||||
$user = api_get_user_entity($userId);
|
||||
$skill = $em->getRepository('ChamiloCoreBundle:Skill')->find($skillId);
|
||||
if (empty($user) || empty($skill)) {
|
||||
exit;
|
||||
}
|
||||
$course = api_get_course_entity($courseId);
|
||||
if (empty($course)) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$session = $em->getRepository('ChamiloCoreBundle:Session')->find($sessionId);
|
||||
/** @var SkillRelItem $skillRelItem */
|
||||
$skillRelItem = $em->getRepository('ChamiloSkillBundle:SkillRelItem')->findOneBy(
|
||||
['itemId' => $itemId, 'itemType' => $typeId, 'skill' => $skillId]
|
||||
);
|
||||
|
||||
if ($skillRelItem) {
|
||||
$criteria = [
|
||||
'user' => $userId,
|
||||
'skillRelItem' => $skillRelItem,
|
||||
];
|
||||
$skillRelItemRelUser = $em->getRepository('ChamiloSkillBundle:SkillRelItemRelUser')->findOneBy($criteria);
|
||||
if ($skillRelItemRelUser) {
|
||||
$em->remove($skillRelItemRelUser);
|
||||
$em->flush();
|
||||
$skillRelItemRelUser = null;
|
||||
} else {
|
||||
$skillRelItemRelUser = new Chamilo\SkillBundle\Entity\SkillRelItemRelUser();
|
||||
$skillRelItemRelUser
|
||||
->setUser($user)
|
||||
->setSkillRelItem($skillRelItem)
|
||||
->setResultId($resultId)
|
||||
->setCreatedBy($creatorId)
|
||||
->setUpdatedBy($creatorId);
|
||||
$em->persist($skillRelItemRelUser);
|
||||
$em->flush();
|
||||
}
|
||||
}
|
||||
echo Skill::getUserSkillStatusLabel($skillRelItem, $skillRelItemRelUser, false, $userId);
|
||||
}
|
||||
break;
|
||||
case 'assign_user_to_skill':
|
||||
$allowSkillInTools = api_get_configuration_value('allow_skill_rel_items');
|
||||
if (empty($allowSkillInTools)) {
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!api_is_allowed_to_edit()) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$skillId = isset($_REQUEST['skill_id']) ? (int) $_REQUEST['skill_id'] : 0;
|
||||
$userId = isset($_REQUEST['user_id']) ? (int) $_REQUEST['user_id'] : 0;
|
||||
$courseId = isset($_REQUEST['course_id']) ? (int) $_REQUEST['course_id'] : 0;
|
||||
$sessionId = isset($_REQUEST['session_id']) ? (int) $_REQUEST['session_id'] : null;
|
||||
|
||||
if (empty($skillId) || empty($userId)) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$em = Database::getManager();
|
||||
$skillRepo = $em->getRepository('ChamiloCoreBundle:Skill');
|
||||
$skill = $skillRepo->find($skillId);
|
||||
$user = api_get_user_entity($userId);
|
||||
|
||||
if (empty($skill) || empty($user)) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$skillUserRepo = $em->getRepository('ChamiloCoreBundle:SkillRelUser');
|
||||
$criteria = [
|
||||
'user' => $user,
|
||||
'skill' => $skill,
|
||||
];
|
||||
$skillRelUsers = $skillUserRepo->findBy($criteria);
|
||||
if (empty($skillRelUsers)) {
|
||||
$skillUser = new \Chamilo\CoreBundle\Entity\SkillRelUser();
|
||||
$skillUser->setUser($user);
|
||||
$skillUser->setSkill($skill);
|
||||
/*if ($showLevels) {
|
||||
$level = $skillLevelRepo->find(intval($values['acquired_level']));
|
||||
$skillUser->setAcquiredLevel($level);
|
||||
}*/
|
||||
|
||||
$course = api_get_course_entity($courseId);
|
||||
$skillUser->setCourse($course);
|
||||
if (!empty($sessionId)) {
|
||||
$session = $em->getRepository('ChamiloCoreBundle:Session')->find($sessionId);
|
||||
$skillUser->setSession($session);
|
||||
}
|
||||
|
||||
$skillUser->setArgumentation('');
|
||||
$skillUser->setArgumentationAuthorId(api_get_user_id());
|
||||
$skillUser->setAcquiredSkillAt(new DateTime());
|
||||
$skillUser->setAssignedBy(0);
|
||||
$em->persist($skillUser);
|
||||
$em->flush();
|
||||
$result = 'success';
|
||||
} else {
|
||||
foreach ($skillRelUsers as $skillRelUser) {
|
||||
$em->remove($skillRelUser);
|
||||
}
|
||||
$em->flush();
|
||||
$result = 'danger';
|
||||
}
|
||||
echo $result;
|
||||
break;
|
||||
default:
|
||||
echo '';
|
||||
}
|
||||
exit;
|
||||
465
main/inc/ajax/social.ajax.php
Normal file
465
main/inc/ajax/social.ajax.php
Normal file
@@ -0,0 +1,465 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use Chamilo\CoreBundle\Entity\Message;
|
||||
use Chamilo\CoreBundle\Entity\MessageFeedback;
|
||||
use ChamiloSession as Session;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
|
||||
/**
|
||||
* Responses to AJAX calls.
|
||||
*/
|
||||
require_once __DIR__.'/../global.inc.php';
|
||||
|
||||
$action = isset($_GET['a']) ? $_GET['a'] : null;
|
||||
|
||||
$current_user_id = api_get_user_id();
|
||||
switch ($action) {
|
||||
case 'add_friend':
|
||||
if (api_is_anonymous()) {
|
||||
echo '';
|
||||
break;
|
||||
}
|
||||
|
||||
if (Security::check_token('get', null, 'invitation')) {
|
||||
$relation_type = USER_RELATION_TYPE_UNKNOWN; //Unknown contact
|
||||
if (isset($_GET['is_my_friend'])) {
|
||||
$relation_type = USER_RELATION_TYPE_FRIEND; //My friend
|
||||
}
|
||||
|
||||
if (isset($_GET['friend_id'])) {
|
||||
$my_current_friend = (int) $_GET['friend_id'];
|
||||
|
||||
if (SocialManager::hasInvitationByUser($current_user_id, $my_current_friend)) {
|
||||
UserManager::relate_users($current_user_id, $my_current_friend, $relation_type);
|
||||
UserManager::relate_users($my_current_friend, $current_user_id, $relation_type);
|
||||
SocialManager::invitation_accepted($my_current_friend, $current_user_id);
|
||||
Display::addFlash(
|
||||
Display::return_message(get_lang('AddedContactToList'), 'success')
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
header('Location: '.api_get_path(WEB_CODE_PATH).'social/invitations.php');
|
||||
exit;
|
||||
case 'deny_friend':
|
||||
if (api_is_anonymous()) {
|
||||
echo '';
|
||||
break;
|
||||
}
|
||||
|
||||
if (Security::check_token('get', null, 'invitation')) {
|
||||
$relation_type = USER_RELATION_TYPE_UNKNOWN; //Contact unknown
|
||||
if (isset($_GET['is_my_friend'])) {
|
||||
$relation_type = USER_RELATION_TYPE_FRIEND; //my friend
|
||||
}
|
||||
if (isset($_GET['denied_friend_id'])) {
|
||||
SocialManager::invitation_denied($_GET['denied_friend_id'], $current_user_id);
|
||||
Display::addFlash(
|
||||
Display::return_message(get_lang('InvitationDenied'), 'success')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
header('Location: '.api_get_path(WEB_CODE_PATH).'social/invitations.php');
|
||||
exit;
|
||||
case 'delete_friend':
|
||||
if (api_is_anonymous()) {
|
||||
echo '';
|
||||
break;
|
||||
}
|
||||
|
||||
if (!Security::check_token('post', null, 'social')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
if (isset($_POST['delete_friend_id'])) {
|
||||
$my_delete_friend = (int) $_POST['delete_friend_id'];
|
||||
SocialManager::remove_user_rel_user($my_delete_friend);
|
||||
|
||||
JsonResponse::create([
|
||||
'secToken' => Security::get_token('social'),
|
||||
])->send();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'show_my_friends':
|
||||
if (api_is_anonymous()) {
|
||||
echo '';
|
||||
break;
|
||||
}
|
||||
$user_id = api_get_user_id();
|
||||
$name_search = Security::remove_XSS($_POST['search_name_q']);
|
||||
|
||||
if (isset($name_search) && $name_search != 'undefined') {
|
||||
$friends = SocialManager::get_friends($user_id, null, $name_search);
|
||||
} else {
|
||||
$friends = SocialManager::get_friends($user_id);
|
||||
}
|
||||
|
||||
$friend_html = '';
|
||||
$number_of_images = 8;
|
||||
$number_friends = count($friends);
|
||||
if ($number_friends != 0) {
|
||||
$number_loop = $number_friends / $number_of_images;
|
||||
$loop_friends = ceil($number_loop);
|
||||
$j = 0;
|
||||
for ($k = 0; $k < $loop_friends; $k++) {
|
||||
if ($j == $number_of_images) {
|
||||
$number_of_images = $number_of_images * 2;
|
||||
}
|
||||
while ($j < $number_of_images) {
|
||||
if (isset($friends[$j])) {
|
||||
$friend = $friends[$j];
|
||||
$user_name = api_xml_http_response_encode($friend['firstName'].' '.$friend['lastName']);
|
||||
$userPicture = UserManager::getUserPicture($friend['friend_user_id']);
|
||||
|
||||
$friend_html .= '
|
||||
<div class="col-md-3">
|
||||
<div class="thumbnail text-center" id="div_'.$friends[$j]['friend_user_id'].'">
|
||||
<img src="'.$userPicture.'" class="img-responsive" id="imgfriend_'.$friend['friend_user_id'].'" title="$user_name">
|
||||
<div class="caption">
|
||||
<h3>
|
||||
<a href="profile.php?u='.$friend['friend_user_id'].'">'.$user_name.'</a>
|
||||
</h3>
|
||||
<p>
|
||||
<button class="btn btn-danger" onclick="delete_friend(this)" id=img_'.$friend['friend_user_id'].'>
|
||||
'.get_lang('Delete').'
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
';
|
||||
}
|
||||
$j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
echo $friend_html;
|
||||
break;
|
||||
case 'toogle_course':
|
||||
if (api_is_anonymous()) {
|
||||
echo '';
|
||||
break;
|
||||
}
|
||||
require_once api_get_path(SYS_CODE_PATH).'forum/forumfunction.inc.php';
|
||||
|
||||
$user_id = Session::read('social_user_id');
|
||||
|
||||
if ($_POST['action']) {
|
||||
$action = $_POST['action'];
|
||||
}
|
||||
|
||||
switch ($action) {
|
||||
case 'load_course':
|
||||
$course_id = intval($_POST['course_code']); // the int course id
|
||||
$course_info = api_get_course_info_by_id($course_id);
|
||||
$course_code = $course_info['code'];
|
||||
|
||||
if (api_is_user_of_course($course_id, api_get_user_id())) {
|
||||
//------Forum messages
|
||||
$forum_result = get_all_post_from_user($user_id, $course_code);
|
||||
$all_result_data = 0;
|
||||
if ($forum_result != '') {
|
||||
echo '<div id="social-forum-main-title">';
|
||||
echo api_xml_http_response_encode(get_lang('Forum'));
|
||||
echo '</div>';
|
||||
|
||||
echo '<div style="background:#FAF9F6; padding:0px;" >';
|
||||
echo api_xml_http_response_encode($forum_result);
|
||||
echo '</div>';
|
||||
echo '<br />';
|
||||
$all_result_data++;
|
||||
}
|
||||
|
||||
//------Blog posts
|
||||
$result = Blog::getBlogPostFromUser($course_id, $user_id, $course_code);
|
||||
|
||||
if (!empty($result)) {
|
||||
api_display_tool_title(api_xml_http_response_encode(get_lang('Blog')));
|
||||
echo '<div style="background:#FAF9F6; padding:0px;">';
|
||||
echo api_xml_http_response_encode($result);
|
||||
echo '</div>';
|
||||
echo '<br />';
|
||||
$all_result_data++;
|
||||
}
|
||||
|
||||
//------Blog comments
|
||||
$result = Blog::getBlogCommentsFromUser($course_id, $user_id, $course_code);
|
||||
if (!empty($result)) {
|
||||
echo '<div style="background:#FAF9F6; padding-left:10px;">';
|
||||
api_display_tool_title(api_xml_http_response_encode(get_lang('BlogComments')));
|
||||
echo api_xml_http_response_encode($result);
|
||||
echo '</div>';
|
||||
echo '<br />';
|
||||
$all_result_data++;
|
||||
}
|
||||
if ($all_result_data == 0) {
|
||||
echo api_xml_http_response_encode(get_lang('NoDataAvailable'));
|
||||
}
|
||||
} else {
|
||||
echo '<div class="clear"></div><br />';
|
||||
api_display_tool_title(api_xml_http_response_encode(get_lang('Details')));
|
||||
echo '<div style="background:#FAF9F6; padding:0px;">';
|
||||
echo api_xml_http_response_encode(get_lang('UserNonRegisteredAtTheCourse'));
|
||||
echo '<div class="clear"></div><br />';
|
||||
echo '</div>';
|
||||
echo '<div class="clear"></div><br />';
|
||||
}
|
||||
break;
|
||||
case 'unload_course':
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'send_comment':
|
||||
if (api_is_anonymous()) {
|
||||
exit;
|
||||
}
|
||||
|
||||
if (api_get_setting('allow_social_tool') !== 'true') {
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!Security::check_token('get', null, 'wall')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$messageId = isset($_GET['id']) ? (int) $_GET['id'] : 0;
|
||||
|
||||
if (empty($messageId)) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$userId = api_get_user_id();
|
||||
$messageInfo = MessageManager::get_message_by_id($messageId);
|
||||
if (!empty($messageInfo)) {
|
||||
$comment = isset($_REQUEST['comment']) ? $_REQUEST['comment'] : '';
|
||||
if (!empty($comment)) {
|
||||
$messageId = SocialManager::sendWallMessage(
|
||||
$userId,
|
||||
$messageInfo['user_receiver_id'],
|
||||
$comment,
|
||||
$messageId,
|
||||
MESSAGE_STATUS_WALL
|
||||
);
|
||||
if ($messageId) {
|
||||
$messageInfo = MessageManager::get_message_by_id($messageId);
|
||||
JsonResponse::create([
|
||||
'secToken' => Security::get_token('wall'),
|
||||
'postHTML' => SocialManager::processPostComment($messageInfo),
|
||||
])->send();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'delete_message':
|
||||
if (api_is_anonymous()) {
|
||||
exit;
|
||||
}
|
||||
|
||||
if (api_get_setting('allow_social_tool') !== 'true') {
|
||||
exit;
|
||||
}
|
||||
|
||||
$messageId = isset($_GET['id']) ? (int) $_GET['id'] : 0;
|
||||
|
||||
if (empty($messageId)) {
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!Security::check_token('get', null, 'social')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$userId = api_get_user_id();
|
||||
$messageInfo = MessageManager::get_message_by_id($messageId);
|
||||
if (!empty($messageInfo)) {
|
||||
$canDelete = ($messageInfo['user_receiver_id'] == $userId || $messageInfo['user_sender_id'] == $userId) &&
|
||||
empty($messageInfo['group_id']);
|
||||
if ($canDelete || api_is_platform_admin()) {
|
||||
SocialManager::deleteMessage($messageId);
|
||||
echo json_encode([
|
||||
'message' => Display::return_message(get_lang('MessageDeleted')),
|
||||
'secToken' => Security::get_token('social'),
|
||||
]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'list_wall_message':
|
||||
if (api_is_anonymous()) {
|
||||
break;
|
||||
}
|
||||
$start = isset($_REQUEST['start']) ? (int) $_REQUEST['start'] : 0;
|
||||
$userId = isset($_REQUEST['u']) ? (int) $_REQUEST['u'] : api_get_user_id();
|
||||
|
||||
$html = '';
|
||||
if ($userId == api_get_user_id()) {
|
||||
$threadList = SocialManager::getThreadList($userId);
|
||||
$threadIdList = [];
|
||||
if (!empty($threadList)) {
|
||||
$threadIdList = array_column($threadList, 'id');
|
||||
}
|
||||
|
||||
$html = SocialManager::getMyWallMessages(
|
||||
$userId,
|
||||
$start,
|
||||
SocialManager::DEFAULT_SCROLL_NEW_POST,
|
||||
$threadIdList
|
||||
);
|
||||
$html = $html['posts'];
|
||||
} else {
|
||||
$messages = SocialManager::getWallMessages(
|
||||
$userId,
|
||||
null,
|
||||
0,
|
||||
0,
|
||||
'',
|
||||
$start,
|
||||
SocialManager::DEFAULT_SCROLL_NEW_POST
|
||||
);
|
||||
$messages = SocialManager::formatWallMessages($messages);
|
||||
|
||||
if (!empty($messages)) {
|
||||
ksort($messages);
|
||||
foreach ($messages as $message) {
|
||||
$post = $message['html'];
|
||||
$comments = SocialManager::getWallPostComments($userId, $message);
|
||||
$html .= SocialManager::wrapPost($message, $post.$comments);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($html)) {
|
||||
$html .= Display::div(
|
||||
Display::url(
|
||||
get_lang('SeeMore'),
|
||||
api_get_self().'?u='.$userId.'&a=list_wall_message&start='.
|
||||
($start + SocialManager::DEFAULT_SCROLL_NEW_POST).'&length='.SocialManager::DEFAULT_SCROLL_NEW_POST,
|
||||
[
|
||||
'class' => 'nextPage',
|
||||
]
|
||||
),
|
||||
[
|
||||
'class' => 'next',
|
||||
]
|
||||
);
|
||||
}
|
||||
echo $html;
|
||||
break;
|
||||
// Read the Url using OpenGraph and returns the hyperlinks content
|
||||
case 'read_url_with_open_graph':
|
||||
api_block_anonymous_users(false);
|
||||
|
||||
$url = $_POST['social_wall_new_msg_main'] ?? '';
|
||||
$url = trim($url);
|
||||
$html = '';
|
||||
if (SocialManager::verifyUrl($url)) {
|
||||
$html = Security::remove_XSS(
|
||||
SocialManager::readContentWithOpenGraph($url)
|
||||
);
|
||||
}
|
||||
echo $html;
|
||||
break;
|
||||
case 'like_message':
|
||||
header('Content-Type: application/json');
|
||||
|
||||
if (
|
||||
api_is_anonymous() ||
|
||||
!api_get_configuration_value('social_enable_messages_feedback')
|
||||
) {
|
||||
echo json_encode(false);
|
||||
exit;
|
||||
}
|
||||
|
||||
$messageId = isset($_GET['id']) ? (int) $_GET['id'] : 0;
|
||||
$status = isset($_GET['status']) ? $_GET['status'] : '';
|
||||
$groupId = isset($_GET['group']) ? (int) $_GET['group'] : 0;
|
||||
|
||||
if (empty($messageId) || !in_array($status, ['like', 'dislike'])) {
|
||||
echo json_encode(false);
|
||||
exit;
|
||||
}
|
||||
|
||||
$em = Database::getManager();
|
||||
$messageRepo = $em->getRepository('ChamiloCoreBundle:Message');
|
||||
$messageLikesRepo = $em->getRepository('ChamiloCoreBundle:MessageFeedback');
|
||||
|
||||
/** @var Message $message */
|
||||
$message = $messageRepo->find($messageId);
|
||||
|
||||
if (empty($message)) {
|
||||
echo json_encode(false);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ((int) $message->getGroupId() !== $groupId) {
|
||||
echo json_encode(false);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!empty($message->getGroupId())) {
|
||||
$usergroup = new UserGroup();
|
||||
$groupInfo = $usergroup->get($groupId);
|
||||
|
||||
if (empty($groupInfo)) {
|
||||
echo json_encode(false);
|
||||
exit;
|
||||
}
|
||||
|
||||
$isMember = $usergroup->is_group_member($groupId, $current_user_id);
|
||||
|
||||
if (GROUP_PERMISSION_CLOSED == $groupInfo['visibility'] && !$isMember) {
|
||||
echo json_encode(false);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
$user = api_get_user_entity($current_user_id);
|
||||
|
||||
$userLike = $messageLikesRepo->findOneBy(['message' => $message, 'user' => $user]);
|
||||
|
||||
if (empty($userLike)) {
|
||||
$userLike = new MessageFeedback();
|
||||
$userLike
|
||||
->setMessage($message)
|
||||
->setUser($user);
|
||||
}
|
||||
|
||||
if ('like' === $status) {
|
||||
if ($userLike->isLiked()) {
|
||||
echo json_encode(false);
|
||||
exit;
|
||||
}
|
||||
|
||||
$userLike
|
||||
->setLiked(true)
|
||||
->setDisliked(false);
|
||||
} elseif ('dislike' === $status) {
|
||||
if ($userLike->isDisliked()) {
|
||||
echo json_encode(false);
|
||||
exit;
|
||||
}
|
||||
|
||||
$userLike
|
||||
->setLiked(false)
|
||||
->setDisliked(true);
|
||||
}
|
||||
|
||||
$userLike
|
||||
->setUpdatedAt(
|
||||
api_get_utc_datetime(null, false, true)
|
||||
);
|
||||
|
||||
$em->persist($userLike);
|
||||
$em->flush();
|
||||
|
||||
echo json_encode(true);
|
||||
break;
|
||||
default:
|
||||
echo '';
|
||||
}
|
||||
exit;
|
||||
1424
main/inc/ajax/statistics.ajax.php
Normal file
1424
main/inc/ajax/statistics.ajax.php
Normal file
File diff suppressed because it is too large
Load Diff
133
main/inc/ajax/student_follow_page.ajax.php
Normal file
133
main/inc/ajax/student_follow_page.ajax.php
Normal file
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use Chamilo\CourseBundle\Entity\CLp;
|
||||
use Chamilo\CourseBundle\Entity\CLpView;
|
||||
use Symfony\Component\HttpFoundation\Request as HttpRequest;
|
||||
|
||||
require_once __DIR__.'/../global.inc.php';
|
||||
|
||||
$httpRequest = HttpRequest::createFromGlobals();
|
||||
|
||||
$isAllowedToEdit = api_is_allowed_to_edit();
|
||||
|
||||
switch ($httpRequest->get('a')) {
|
||||
case 'form_adquisition':
|
||||
displayForm(
|
||||
$httpRequest->query->getInt('lp_view')
|
||||
);
|
||||
break;
|
||||
case 'views_invisible':
|
||||
processViewsInvisible(
|
||||
$httpRequest->request->get('chkb_view') ?: [],
|
||||
$httpRequest->request->getBoolean('state')
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
function displayForm(int $lpViewId)
|
||||
{
|
||||
$em = Database::getManager();
|
||||
|
||||
$lpView = $em->find(CLpView::class, $lpViewId);
|
||||
|
||||
if (null === $lpView) {
|
||||
return;
|
||||
}
|
||||
|
||||
$lp = $em->find(CLp::class, $lpView->getLpId());
|
||||
|
||||
$extraField = new ExtraField('lp_view');
|
||||
$field = $extraField->get_handler_field_info_by_field_variable(StudentFollowPage::VARIABLE_ACQUISITION);
|
||||
|
||||
$extraFieldValue = new ExtraFieldValue('lp_view');
|
||||
$value = $extraFieldValue->get_values_by_handler_and_field_variable(
|
||||
$lpViewId,
|
||||
StudentFollowPage::VARIABLE_ACQUISITION
|
||||
);
|
||||
|
||||
$options = [];
|
||||
|
||||
foreach ($field['options'] as $option) {
|
||||
$options[$option['option_value']] = ExtraFieldOption::translateDisplayName($option['display_text']);
|
||||
}
|
||||
|
||||
$frmId = 'frm_lp_acquisition_'.$lpView->getLpId();
|
||||
$frmAction = api_get_self().'?'.http_build_query(['lp_view' => $lpViewId, 'a' => 'form_adquisition']);
|
||||
|
||||
$form = new FormValidator($frmId, 'post', $frmAction);
|
||||
$form->addRadio(StudentFollowPage::VARIABLE_ACQUISITION, get_lang('Acquisition'), $options);
|
||||
$form->addHidden('lp_view', $lpViewId);
|
||||
$form->addButtonSave(get_lang('Save'));
|
||||
|
||||
if ($form->validate()) {
|
||||
$values = $form->exportValues();
|
||||
|
||||
$extraFieldValue = new ExtraFieldValue('lp_view');
|
||||
$extraFieldValue->save(
|
||||
[
|
||||
'variable' => StudentFollowPage::VARIABLE_ACQUISITION,
|
||||
'item_id' => $lpViewId,
|
||||
'comment' => json_encode(['user' => api_get_user_id(), 'datetime' => api_get_utc_datetime()]),
|
||||
'value' => $values[StudentFollowPage::VARIABLE_ACQUISITION],
|
||||
]
|
||||
);
|
||||
|
||||
echo StudentFollowPage::getLpAcquisition(
|
||||
[
|
||||
'iid' => $lp->getIid(),
|
||||
'lp_name' => $lp->getName(),
|
||||
],
|
||||
$lpView->getUserId(),
|
||||
$lpView->getCId(),
|
||||
$lpView->getSessionId(),
|
||||
true
|
||||
);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!empty($value)) {
|
||||
$form->setDefaults([StudentFollowPage::VARIABLE_ACQUISITION => $value['value']]);
|
||||
}
|
||||
|
||||
echo $form->returnForm()
|
||||
."<script>$(function () {
|
||||
$('#$frmId').on('submit', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
var self = $(this);
|
||||
|
||||
self.find(':submit').prop('disabled', true);
|
||||
|
||||
$.post(this.action, self.serialize()).done(function (response) {
|
||||
$('#acquisition-$lpViewId').html(response);
|
||||
|
||||
$('#global-modal').modal('hide');
|
||||
|
||||
self.find(':submit').prop('disabled', false);
|
||||
});
|
||||
})
|
||||
})</script>";
|
||||
}
|
||||
|
||||
function processViewsInvisible(array $lpViews, bool $state)
|
||||
{
|
||||
foreach ($lpViews as $lpViewData) {
|
||||
$parts = explode('_', $lpViewData);
|
||||
|
||||
[$lpId, $userId, $courseId, $sessionId] = array_map('intval', $parts);
|
||||
|
||||
$lpView = learnpath::findLastView($lpId, $userId, $courseId, $sessionId, true);
|
||||
|
||||
$extraFieldValue = new ExtraFieldValue('lp_view');
|
||||
$extraFieldValue->save(
|
||||
[
|
||||
'variable' => StudentFollowPage::VARIABLE_INVISIBLE,
|
||||
'item_id' => $lpView['iid'],
|
||||
'comment' => json_encode(['user' => api_get_user_id(), 'datetime' => api_get_utc_datetime()]),
|
||||
'value' => $state,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
59
main/inc/ajax/survey.ajax.php
Normal file
59
main/inc/ajax/survey.ajax.php
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
require_once __DIR__.'/../global.inc.php';
|
||||
|
||||
$current_user_id = api_get_user_id();
|
||||
$courseId = api_get_course_int_id();
|
||||
|
||||
$action = isset($_GET['a']) ? $_GET['a'] : null;
|
||||
$surveyId = isset($_REQUEST['survey_id']) ? $_REQUEST['survey_id'] : 0;
|
||||
$questionId = isset($_REQUEST['question_id']) ? $_REQUEST['question_id'] : 0;
|
||||
|
||||
switch ($action) {
|
||||
case 'load_question_options':
|
||||
if (!api_is_allowed_to_edit(false, true)) {
|
||||
exit;
|
||||
}
|
||||
$question = SurveyManager::get_question($questionId);
|
||||
if (!empty($question) && !empty($question['answer_data'])) {
|
||||
$optionList = [];
|
||||
foreach ($question['answer_data'] as $answer) {
|
||||
$optionList[$answer['iid']] = strip_tags($answer['data']);
|
||||
}
|
||||
echo json_encode($optionList);
|
||||
}
|
||||
break;
|
||||
case 'save_question':
|
||||
if (api_is_anonymous()) {
|
||||
echo '';
|
||||
break;
|
||||
}
|
||||
$status = isset($_GET['status']) ? (int) $_GET['status'] : null;
|
||||
$userId = api_get_user_id();
|
||||
|
||||
$surveyData = SurveyManager::get_survey($surveyId);
|
||||
|
||||
if (empty($surveyData)) {
|
||||
exit;
|
||||
}
|
||||
|
||||
SurveyUtil::remove_answer(
|
||||
$userId,
|
||||
$surveyId,
|
||||
$questionId,
|
||||
$courseId
|
||||
);
|
||||
|
||||
SurveyUtil::store_answer(
|
||||
$userId,
|
||||
$surveyId,
|
||||
$questionId,
|
||||
1,
|
||||
$status,
|
||||
$surveyData
|
||||
);
|
||||
|
||||
break;
|
||||
}
|
||||
exit;
|
||||
161
main/inc/ajax/thematic.ajax.php
Normal file
161
main/inc/ajax/thematic.ajax.php
Normal file
@@ -0,0 +1,161 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Responses to AJAX calls for thematic.
|
||||
*/
|
||||
require_once __DIR__.'/../global.inc.php';
|
||||
api_protect_course_script(true);
|
||||
|
||||
$action = $_GET['a'];
|
||||
$thematic = new Thematic();
|
||||
|
||||
switch ($action) {
|
||||
case 'save_thematic_plan':
|
||||
/*$title_list = $_REQUEST['title'];
|
||||
$description_list = $_REQUEST['desc'];
|
||||
//$description_list = $_REQUEST['description'];
|
||||
$description_type = $_REQUEST['description_type'];
|
||||
if (api_is_allowed_to_edit(null, true)) {
|
||||
for($i=1;$i<count($title_list)+1; $i++) {
|
||||
$thematic->set_thematic_plan_attributes($_REQUEST['thematic_id'], $title_list[$i], $description_list[$i], $description_type[$i]);
|
||||
$affected_rows = $thematic->thematic_plan_save();
|
||||
}
|
||||
}
|
||||
$thematic_plan_data = $thematic->get_thematic_plan_data();
|
||||
$return = $thematic->get_thematic_plan_div($thematic_plan_data);
|
||||
echo $return[$_REQUEST['thematic_id']];*/
|
||||
break;
|
||||
case 'save_thematic_advance':
|
||||
if (!api_is_allowed_to_edit(null, true)) {
|
||||
echo '';
|
||||
exit;
|
||||
}
|
||||
/*
|
||||
if (($_REQUEST['start_date_type'] == 1 && empty($_REQUEST['start_date_by_attendance'])) || (!empty($_REQUEST['duration_in_hours']) && !is_numeric($_REQUEST['duration_in_hours'])) ) {
|
||||
if ($_REQUEST['start_date_type'] == 1 && empty($_REQUEST['start_date_by_attendance'])) {
|
||||
$start_date_error = true;
|
||||
$data['start_date_error'] = $start_date_error;
|
||||
}
|
||||
|
||||
if (!empty($_REQUEST['duration_in_hours']) && !is_numeric($_REQUEST['duration_in_hours'])) {
|
||||
$duration_error = true;
|
||||
$data['duration_error'] = $duration_error;
|
||||
}
|
||||
|
||||
$data['action'] = $_REQUEST['action'];
|
||||
$data['thematic_id'] = $_REQUEST['thematic_id'];
|
||||
$data['attendance_select'] = $attendance_select;
|
||||
if (isset($_REQUEST['thematic_advance_id'])) {
|
||||
$data['thematic_advance_id'] = $_REQUEST['thematic_advance_id'];
|
||||
$thematic_advance_data = $thematic->get_thematic_advance_list($_REQUEST['thematic_advance_id']);
|
||||
$data['thematic_advance_data'] = $thematic_advance_data;
|
||||
}
|
||||
} else {
|
||||
if ($_REQUEST['thematic_advance_token'] == $_SESSION['thematic_advance_token'] && api_is_allowed_to_edit(null, true)) {
|
||||
$thematic_advance_id = $_REQUEST['thematic_advance_id'];
|
||||
$thematic_id = $_REQUEST['thematic_id'];
|
||||
$content = $_REQUEST['real_content'];
|
||||
$duration = $_REQUEST['duration_in_hours'];
|
||||
if (isset($_REQUEST['start_date_type']) && $_REQUEST['start_date_type'] == 2) {
|
||||
$start_date = $thematic->build_datetime_from_array($_REQUEST['custom_start_date']);
|
||||
$attendance_id = 0;
|
||||
} else {
|
||||
$start_date = $_REQUEST['start_date_by_attendance'];
|
||||
$attendance_id = $_REQUEST['attendance_select'];
|
||||
}
|
||||
$thematic->set_thematic_advance_attributes($thematic_advance_id, $thematic_id, $attendance_id, $content, $start_date, $duration);
|
||||
$affected_rows = $thematic->thematic_advance_save();
|
||||
if ($affected_rows) {
|
||||
// get last done thematic advance before move thematic list
|
||||
$last_done_thematic_advance = $thematic->get_last_done_thematic_advance();
|
||||
// update done advances with de current thematic list
|
||||
if (!empty($last_done_thematic_advance)) {
|
||||
$update_done_advances = $thematic->update_done_thematic_advances($last_done_thematic_advance);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$thematic_advance_data = $thematic->get_thematic_advance_list(null, null, true);
|
||||
$return = $thematic->get_thematic_advance_div($thematic_advance_data);
|
||||
echo $return[$_REQUEST['thematic_id']][$_REQUEST['thematic_advance_id']];*/
|
||||
break;
|
||||
case 'get_datetime_by_attendance':
|
||||
$attendance_id = intval($_REQUEST['attendance_id']);
|
||||
$thematic_advance_id = intval($_REQUEST['thematic_advance_id']);
|
||||
|
||||
$label = '';
|
||||
$input_select = '';
|
||||
if (!empty($attendance_id)) {
|
||||
$attendance = new Attendance();
|
||||
$thematic = new Thematic();
|
||||
$thematic_list = $thematic->get_thematic_list();
|
||||
|
||||
$my_list = $thematic_list_temp = [];
|
||||
foreach ($thematic_list as $item) {
|
||||
$my_list = $thematic->get_thematic_advance_by_thematic_id($item['id']);
|
||||
$thematic_list_temp = array_merge($my_list, $thematic_list_temp);
|
||||
}
|
||||
$new_thematic_list = [];
|
||||
|
||||
foreach ($thematic_list_temp as $item) {
|
||||
if (!empty($item['attendance_id'])) {
|
||||
$new_thematic_list[$item['id']] = [
|
||||
'attendance_id' => $item['attendance_id'],
|
||||
'start_date' => $item['start_date'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$attendance_calendar = $attendance->get_attendance_calendar($attendance_id);
|
||||
|
||||
$label = get_lang('StartDate');
|
||||
if (!empty($attendance_calendar)) {
|
||||
$input_select .= '<select id="start_date_select_calendar" name="start_date_by_attendance" size="7" class="form-control">';
|
||||
foreach ($attendance_calendar as $calendar) {
|
||||
$selected = null;
|
||||
$insert = true;
|
||||
//checking if was already taken
|
||||
foreach ($new_thematic_list as $key => $thematic_item) {
|
||||
if ($calendar['db_date_time'] == $thematic_item['start_date']) {
|
||||
$insert = false;
|
||||
if ($thematic_advance_id == $key) {
|
||||
$insert = true;
|
||||
$selected = 'selected';
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($insert == true) {
|
||||
$input_select .= '<option '.$selected.' value="'.$calendar['date_time'].'">'.$calendar['date_time'].'</option>';
|
||||
}
|
||||
}
|
||||
$input_select .= '</select>';
|
||||
} else {
|
||||
$input_select .= '<em>'.get_lang('ThereAreNoRegisteredDatetimeYet').'</em>';
|
||||
}
|
||||
}
|
||||
?>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-2 control-label"><?php echo $label; ?></label>
|
||||
<div class="col-sm-8"><?php echo $input_select; ?></div>
|
||||
</div>
|
||||
<?php
|
||||
break;
|
||||
case 'update_done_thematic_advance':
|
||||
$thematic_advance_id = intval($_GET['thematic_advance_id']);
|
||||
$total_average = 0;
|
||||
if (!empty($thematic_advance_id)) {
|
||||
$thematic = new Thematic();
|
||||
$affected_rows = $thematic->update_done_thematic_advances($thematic_advance_id);
|
||||
$total_average = $thematic->get_total_average_of_thematic_advances(
|
||||
api_get_course_id(),
|
||||
api_get_session_id()
|
||||
);
|
||||
}
|
||||
echo $total_average;
|
||||
break;
|
||||
default:
|
||||
echo '';
|
||||
}
|
||||
exit;
|
||||
15
main/inc/ajax/timeline.ajax.php
Normal file
15
main/inc/ajax/timeline.ajax.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
require_once __DIR__.'/../global.inc.php';
|
||||
|
||||
$timeline = new Timeline();
|
||||
|
||||
$action = $_GET['a'];
|
||||
|
||||
switch ($action) {
|
||||
case 'get_timeline_content':
|
||||
$items = $timeline->get_timeline_content($_GET['id']);
|
||||
echo json_encode($items);
|
||||
break;
|
||||
}
|
||||
549
main/inc/ajax/user_manager.ajax.php
Normal file
549
main/inc/ajax/user_manager.ajax.php
Normal file
@@ -0,0 +1,549 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use Chamilo\UserBundle\Entity\User;
|
||||
use Doctrine\Common\Collections\Criteria;
|
||||
use Doctrine\ORM\Query\Expr\Join;
|
||||
use Symfony\Component\HttpFoundation\Request as HttpRequest;
|
||||
|
||||
/**
|
||||
* Responses to AJAX calls.
|
||||
*/
|
||||
require_once __DIR__.'/../global.inc.php';
|
||||
|
||||
$request = HttpRequest::createFromGlobals();
|
||||
$isRequestByAjax = $request->isXmlHttpRequest();
|
||||
|
||||
$action = $_REQUEST['a'];
|
||||
|
||||
switch ($action) {
|
||||
case 'comment_attendance':
|
||||
$selected = $_REQUEST['selected'];
|
||||
$comment = $_REQUEST['comment'];
|
||||
$attendanceId = (int) $_REQUEST['attendance_id'];
|
||||
if (!empty($selected)) {
|
||||
list($prefix, $userId, $attendanceCalendarId) = explode('-', $selected);
|
||||
$attendance = new Attendance();
|
||||
$attendance->saveComment(
|
||||
(int) $userId,
|
||||
(int) $attendanceCalendarId,
|
||||
$comment,
|
||||
$attendanceId
|
||||
);
|
||||
echo 1;
|
||||
exit;
|
||||
}
|
||||
echo 0;
|
||||
break;
|
||||
case 'get_attendance_comment':
|
||||
$selected = $_REQUEST['selected'];
|
||||
if (!empty($selected)) {
|
||||
list($prefix, $userId, $attendanceCalendarId) = explode('-', $selected);
|
||||
$attendance = new Attendance();
|
||||
$commentInfo = $attendance->getComment(
|
||||
(int) $userId,
|
||||
(int) $attendanceCalendarId
|
||||
);
|
||||
echo json_encode(
|
||||
[
|
||||
'comment' => $commentInfo['comment'],
|
||||
'author' => !empty($commentInfo['author']) ? get_lang('Author').': '.$commentInfo['author'] : '',
|
||||
]
|
||||
);
|
||||
}
|
||||
break;
|
||||
case 'block_attendance_calendar':
|
||||
$calendarId = (int) $_REQUEST['calendar_id'];
|
||||
$attendance = new Attendance();
|
||||
$attendance->updateCalendarBlocked($calendarId);
|
||||
echo (int) $attendance->isCalendarBlocked($calendarId);
|
||||
break;
|
||||
case 'get_attendance_sign':
|
||||
$selected = $_REQUEST['selected'];
|
||||
if (!empty($selected)) {
|
||||
list($prefix, $userId, $attendanceCalendarId) = explode('-', $selected);
|
||||
$attendance = new Attendance();
|
||||
$signature = $attendance->getSignature($userId, $attendanceCalendarId);
|
||||
echo $signature;
|
||||
}
|
||||
break;
|
||||
case 'remove_attendance_sign':
|
||||
$selected = $_REQUEST['selected'];
|
||||
$attendanceId = (int) $_REQUEST['attendance_id'];
|
||||
if (!empty($selected)) {
|
||||
list($prefix, $userId, $attendanceCalendarId) = explode('-', $selected);
|
||||
$attendance = new Attendance();
|
||||
$attendance->deleteSignature($userId, $attendanceCalendarId, $attendanceId);
|
||||
}
|
||||
break;
|
||||
case 'sign_attendance':
|
||||
$selected = $_REQUEST['selected'];
|
||||
$file = isset($_REQUEST['file']) ? $_REQUEST['file'] : '';
|
||||
$file = str_replace(' ', '+', $file);
|
||||
$attendanceId = $_REQUEST['attendance_id'];
|
||||
if (!empty($selected)) {
|
||||
list($prefix, $userId, $attendanceCalendarId, $courseId) = explode('-', $selected);
|
||||
$attendance = new Attendance();
|
||||
$attendance->saveSignature($userId, $attendanceCalendarId, $file, $attendanceId, $courseId);
|
||||
echo 1;
|
||||
exit;
|
||||
}
|
||||
echo 0;
|
||||
break;
|
||||
case 'set_expiration_date':
|
||||
$status = (int) $_REQUEST['status'];
|
||||
$dates = UserManager::getExpirationDateByRole($status);
|
||||
echo json_encode($dates);
|
||||
break;
|
||||
case 'get_user_like':
|
||||
if (api_is_platform_admin() || api_is_drh() || api_is_session_admin()) {
|
||||
$query = $_REQUEST['q'];
|
||||
$conditions = [
|
||||
'username' => $query,
|
||||
'firstname' => $query,
|
||||
'lastname' => $query,
|
||||
];
|
||||
$users = UserManager::getUserListLike($conditions, [], false, 'OR');
|
||||
$result = [];
|
||||
if (!empty($users)) {
|
||||
foreach ($users as $user) {
|
||||
$result[] = ['id' => $user['id'], 'text' => $user['complete_name'].' ('.$user['username'].')'];
|
||||
}
|
||||
$result['items'] = $result;
|
||||
}
|
||||
echo json_encode($result);
|
||||
}
|
||||
break;
|
||||
case 'get_user_popup':
|
||||
if (!$isRequestByAjax) {
|
||||
break;
|
||||
}
|
||||
|
||||
$courseId = (int) $request->get('course_id');
|
||||
$sessionId = (int) $request->get('session_id');
|
||||
$hash = (string) $request->get('hash');
|
||||
$userId = (int) UserManager::decryptUserHash($hash);
|
||||
|
||||
$user_info = api_get_user_info($userId);
|
||||
|
||||
if (empty($user_info)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ($courseId) {
|
||||
$courseInfo = api_get_course_info_by_id($courseId);
|
||||
|
||||
if (empty($courseInfo)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($sessionId) {
|
||||
$sessionInfo = api_get_session_info($sessionId);
|
||||
|
||||
if (empty($sessionInfo)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$isAnonymous = api_is_anonymous();
|
||||
|
||||
if ($isAnonymous && empty($courseId)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ($isAnonymous && $courseId) {
|
||||
if ('false' === api_get_setting('course_catalog_published')) {
|
||||
break;
|
||||
}
|
||||
|
||||
$coursesNotInCatalog = CoursesAndSessionsCatalog::getCoursesToAvoid();
|
||||
|
||||
if (in_array($courseId, $coursesNotInCatalog)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
echo '<div class="row">';
|
||||
echo '<div class="col-sm-5">';
|
||||
echo '<div class="thumbnail">';
|
||||
echo Display::img($user_info['avatar'], $user_info['complete_name']);
|
||||
echo '</div>';
|
||||
echo '</div>';
|
||||
|
||||
echo '<div class="col-sm-7">';
|
||||
|
||||
if ($isAnonymous || api_get_setting('show_email_addresses') == 'false') {
|
||||
$user_info['mail'] = '';
|
||||
}
|
||||
|
||||
$userData = '<h3>'.$user_info['complete_name'].'</h3>'
|
||||
.PHP_EOL
|
||||
.$user_info['mail']
|
||||
.PHP_EOL
|
||||
.$user_info['official_code'];
|
||||
|
||||
if ($isAnonymous) {
|
||||
// Only allow anonymous users to see user popup if the popup user
|
||||
// is a teacher (which might be necessary to illustrate a course)
|
||||
if ((int) $user_info['status'] === COURSEMANAGER) {
|
||||
echo $userData;
|
||||
}
|
||||
} else {
|
||||
echo Display::url(
|
||||
$userData,
|
||||
api_get_path(WEB_CODE_PATH).'social/profile.php?u='.$user_info['user_id']
|
||||
);
|
||||
}
|
||||
echo '</div>';
|
||||
echo '</div>';
|
||||
|
||||
$url = api_get_path(WEB_AJAX_PATH).'message.ajax.php?'
|
||||
.http_build_query(
|
||||
[
|
||||
'a' => 'send_message',
|
||||
'user_id' => $user_info['user_id'],
|
||||
'course_id' => $courseId,
|
||||
'session_id' => $sessionId,
|
||||
]
|
||||
);
|
||||
|
||||
if ($isAnonymous === false &&
|
||||
api_get_setting('allow_message_tool') == 'true'
|
||||
) {
|
||||
echo '<script>';
|
||||
echo '
|
||||
$("#send_message_link").on("click", function() {
|
||||
var url = "'.$url.'";
|
||||
var params = $("#send_message").serialize();
|
||||
$.ajax({
|
||||
url: url+"&"+params,
|
||||
success:function(data) {
|
||||
$("#subject_id").val("");
|
||||
$("#content_id").val("");
|
||||
$("#send_message").html(data);
|
||||
$("#send_message_link").hide();
|
||||
}
|
||||
});
|
||||
});';
|
||||
|
||||
echo '</script>';
|
||||
echo MessageManager::generate_message_form();
|
||||
echo '
|
||||
<div class="row">
|
||||
<div class="col-sm-10 col-sm-offset-2">
|
||||
<a class="btn btn-primary" id="send_message_link">
|
||||
<em class="fa fa-envelope"></em> '.get_lang('Send').'
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
';
|
||||
}
|
||||
break;
|
||||
case 'user_id_exists':
|
||||
if (api_is_anonymous()) {
|
||||
echo '';
|
||||
} else {
|
||||
if (UserManager::is_user_id_valid($_GET['user_id'])) {
|
||||
echo 1;
|
||||
} else {
|
||||
echo 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'search_tags':
|
||||
header('Content-Type: application/json');
|
||||
|
||||
$result = ['items' => []];
|
||||
|
||||
if (api_is_anonymous()) {
|
||||
echo json_encode($result);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!isset($_GET['q'], $_GET['field_id'])) {
|
||||
echo json_encode($result);
|
||||
break;
|
||||
}
|
||||
|
||||
$result['items'] = UserManager::get_tags($_GET['q'], $_GET['field_id'], null, '10');
|
||||
echo json_encode($result);
|
||||
break;
|
||||
case 'generate_api_key':
|
||||
if (api_is_anonymous()) {
|
||||
echo '';
|
||||
} else {
|
||||
$array_list_key = [];
|
||||
$user_id = api_get_user_id();
|
||||
$api_service = 'dokeos';
|
||||
$num = UserManager::update_api_key($user_id, $api_service);
|
||||
$array_list_key = UserManager::get_api_keys($user_id, $api_service); ?>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-2 control-label"><?php echo get_lang('MyApiKey'); ?></label>
|
||||
<div class="col-sm-8">
|
||||
<input type="text" name="api_key_generate" id="id_api_key_generate" class="form-control" value="<?php echo $array_list_key[$num]; ?>"/>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
break;
|
||||
case 'active_user':
|
||||
$allow = api_get_configuration_value('allow_disable_user_for_session_admin');
|
||||
if ((api_is_platform_admin() && api_global_admin_can_edit_admin($_GET['user_id'])) ||
|
||||
(
|
||||
$allow &&
|
||||
api_is_session_admin() &&
|
||||
api_global_admin_can_edit_admin($_GET['user_id'], null, true)
|
||||
)
|
||||
) {
|
||||
$user_id = intval($_GET['user_id']);
|
||||
$status = intval($_GET['status']);
|
||||
|
||||
if (!empty($user_id)) {
|
||||
$user_table = Database::get_main_table(TABLE_MAIN_USER);
|
||||
$sql = "UPDATE $user_table
|
||||
SET active = '".$status."'
|
||||
WHERE user_id = '".$user_id."'";
|
||||
$result = Database::query($sql);
|
||||
|
||||
// Send and email if account is active
|
||||
if ($status == 1) {
|
||||
$user_info = api_get_user_info($user_id);
|
||||
$recipientName = api_get_person_name(
|
||||
$user_info['firstname'],
|
||||
$user_info['lastname'],
|
||||
null,
|
||||
PERSON_NAME_EMAIL_ADDRESS
|
||||
);
|
||||
|
||||
$subject = '['.api_get_setting('siteName').'] '.get_lang('YourReg').' '.api_get_setting('siteName');
|
||||
$emailAdmin = api_get_setting('emailAdministrator');
|
||||
$sender_name = api_get_person_name(
|
||||
api_get_setting('administratorName'),
|
||||
api_get_setting('administratorSurname'),
|
||||
null,
|
||||
PERSON_NAME_EMAIL_ADDRESS
|
||||
);
|
||||
$body = get_lang('Dear')." ".stripslashes($recipientName).",\n\n";
|
||||
$body .= sprintf(
|
||||
get_lang('YourAccountOnXHasJustBeenApprovedByOneOfOurAdministrators'),
|
||||
api_get_setting('siteName')
|
||||
)."\n";
|
||||
$body .= sprintf(
|
||||
get_lang('YouCanNowLoginAtXUsingTheLoginAndThePasswordYouHaveProvided'),
|
||||
api_get_path(WEB_PATH)
|
||||
).",\n\n";
|
||||
$body .= get_lang('HaveFun')."\n\n";
|
||||
//$body.=get_lang('Problem'). "\n\n". get_lang('SignatureFormula');
|
||||
$body .= api_get_person_name(
|
||||
api_get_setting('administratorName'),
|
||||
api_get_setting('administratorSurname')
|
||||
)."\n".
|
||||
get_lang('Manager')." ".
|
||||
api_get_setting('siteName')."\nT. ".api_get_setting('administratorTelephone')."\n".
|
||||
get_lang('Email')." : ".api_get_setting('emailAdministrator');
|
||||
|
||||
$additionalParameters = [
|
||||
'smsType' => SmsPlugin::ACCOUNT_APPROVED_CONNECT,
|
||||
'userId' => $user_id,
|
||||
];
|
||||
|
||||
MessageManager::send_message_simple(
|
||||
$user_id,
|
||||
$subject,
|
||||
$body,
|
||||
null,
|
||||
false,
|
||||
false,
|
||||
$additionalParameters
|
||||
);
|
||||
Event::addEvent(LOG_USER_ENABLE, LOG_USER_ID, $user_id);
|
||||
} else {
|
||||
Event::addEvent(LOG_USER_DISABLE, LOG_USER_ID, $user_id);
|
||||
}
|
||||
echo $status;
|
||||
}
|
||||
} else {
|
||||
echo '-1';
|
||||
}
|
||||
break;
|
||||
case 'user_by_role':
|
||||
if (!api_is_platform_admin()) {
|
||||
api_not_allowed(false, null, 403);
|
||||
}
|
||||
|
||||
$status = isset($_REQUEST['status']) ? (int) $_REQUEST['status'] : DRH;
|
||||
$active = isset($_REQUEST['active']) ? (int) $_REQUEST['active'] : null;
|
||||
|
||||
$criteria = new Criteria();
|
||||
$criteria
|
||||
->where(
|
||||
Criteria::expr()->orX(
|
||||
Criteria::expr()->contains('username', $_REQUEST['q']),
|
||||
Criteria::expr()->contains('firstname', $_REQUEST['q']),
|
||||
Criteria::expr()->contains('lastname', $_REQUEST['q'])
|
||||
)
|
||||
)
|
||||
->andWhere(
|
||||
Criteria::expr()->eq('status', $status)
|
||||
);
|
||||
|
||||
if (null !== $active) {
|
||||
$criteria->andWhere(Criteria::expr()->eq('active', $active));
|
||||
}
|
||||
$users = UserManager::getRepository()->matching($criteria);
|
||||
|
||||
if (!$users->count()) {
|
||||
echo json_encode([]);
|
||||
break;
|
||||
}
|
||||
|
||||
$items = [];
|
||||
|
||||
/** @var User $user */
|
||||
foreach ($users as $user) {
|
||||
$items[] = [
|
||||
'id' => $user->getId(),
|
||||
'text' => UserManager::formatUserFullName($user, true),
|
||||
];
|
||||
}
|
||||
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode(['items' => $items]);
|
||||
break;
|
||||
case 'teacher_to_basis_course':
|
||||
api_block_anonymous_users(false);
|
||||
|
||||
$sortByFirstName = api_sort_by_first_name();
|
||||
$urlId = api_get_current_access_url_id();
|
||||
|
||||
$qb = UserManager::getRepository()->createQueryBuilder('u');
|
||||
$qb->where(
|
||||
$qb->expr()->orX(
|
||||
$qb->expr()->like('u.username', ':q'),
|
||||
$qb->expr()->like('u.firstname', ':q'),
|
||||
$qb->expr()->like('u.lastname', ':q')
|
||||
)
|
||||
);
|
||||
|
||||
if (api_is_multiple_url_enabled()) {
|
||||
$qb
|
||||
->innerJoin('ChamiloCoreBundle:AccessUrlRelUser', 'uru', Join::WITH, 'u.userId = uru.userId')
|
||||
->andWhere('uru.accessUrlId = '.$urlId);
|
||||
}
|
||||
|
||||
$qb
|
||||
->andWhere(
|
||||
$qb->expr()->in('u.status', UserManager::getAllowedRolesAsTeacher())
|
||||
)
|
||||
->orderBy(
|
||||
$sortByFirstName
|
||||
? 'u.firstname, u.lastname'
|
||||
: 'u.lastname, u.firstname'
|
||||
)
|
||||
->setParameter('q', '%'.$_REQUEST['q'].'%');
|
||||
|
||||
$users = $qb->getQuery()->getResult();
|
||||
|
||||
if (!$users) {
|
||||
echo json_encode([]);
|
||||
break;
|
||||
}
|
||||
|
||||
$items = [];
|
||||
|
||||
/** @var User $user */
|
||||
foreach ($users as $user) {
|
||||
$items[] = [
|
||||
'id' => $user->getId(),
|
||||
'text' => UserManager::formatUserFullName($user, true),
|
||||
];
|
||||
}
|
||||
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode(['items' => $items]);
|
||||
break;
|
||||
case 'update_users':
|
||||
$usersData = json_decode($_POST['users'], true);
|
||||
$updatedCount = 0;
|
||||
|
||||
foreach ($usersData as $userData) {
|
||||
if (empty($userData['user_id'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$userId = (int) $userData['user_id'];
|
||||
$currentUserData = api_get_user_info($userId);
|
||||
|
||||
if (!$currentUserData) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$updatedData = [
|
||||
'firstname' => $userData['firstname'] ?? $currentUserData['firstname'],
|
||||
'lastname' => $userData['lastname'] ?? $currentUserData['lastname'],
|
||||
'email' => $userData['email'] ?? $currentUserData['email'],
|
||||
'phone' => $userData['phone'] ?? $currentUserData['phone'],
|
||||
'official_code' => $userData['official_code'] ?? $currentUserData['official_code'],
|
||||
'status' => isset($userData['status']) ? (int) $userData['status'] : $currentUserData['status'],
|
||||
'active' => isset($userData['active']) ? (int) $userData['active'] : $currentUserData['active'],
|
||||
];
|
||||
|
||||
if (!empty($userData['password'])) {
|
||||
$updatedData['password'] = $userData['password'];
|
||||
}
|
||||
|
||||
$extraFieldHandler = new ExtraField('user');
|
||||
$extraFieldValue = new ExtraFieldValue('user');
|
||||
$extraFields = [];
|
||||
foreach ($userData as $key => &$value) {
|
||||
if (strpos($key, 'extra_') === 0) {
|
||||
$fieldName = str_replace('extra_', '', $key);
|
||||
$fieldInfo = $extraFieldHandler->get_handler_field_info_by_field_variable($fieldName);
|
||||
if ($fieldInfo) {
|
||||
if ($fieldInfo['field_type'] == 10 && is_string($value) && strpos($value, ',') !== false) {
|
||||
$value = explode(',', $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UserManager::update_user(
|
||||
$userId,
|
||||
$updatedData['firstname'],
|
||||
$updatedData['lastname'],
|
||||
$currentUserData['username'],
|
||||
$updatedData['password'] ?? null,
|
||||
$currentUserData['auth_source'],
|
||||
$updatedData['email'],
|
||||
$updatedData['status'],
|
||||
$updatedData['official_code'],
|
||||
$updatedData['phone'],
|
||||
$currentUserData['picture_uri'],
|
||||
null,
|
||||
$updatedData['active'],
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
$currentUserData['language']
|
||||
);
|
||||
|
||||
$userData['item_id'] = $userId;
|
||||
$extraFieldValue->saveFieldValues(
|
||||
$userData,
|
||||
false,
|
||||
false,
|
||||
[],
|
||||
[],
|
||||
true
|
||||
);
|
||||
|
||||
$updatedCount++;
|
||||
}
|
||||
|
||||
echo json_encode(['message' => get_lang('Saved').' '.$updatedCount]);
|
||||
break;
|
||||
default:
|
||||
echo '';
|
||||
}
|
||||
exit;
|
||||
57
main/inc/ajax/usergroup.ajax.php
Normal file
57
main/inc/ajax/usergroup.ajax.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Responses to AJAX calls.
|
||||
*/
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request as HttpRequest;
|
||||
|
||||
require_once __DIR__.'/../global.inc.php';
|
||||
|
||||
$httpRequest = HttpRequest::createFromGlobals();
|
||||
|
||||
$action = $httpRequest->query->has('a') ? $httpRequest->query->get('a') : $httpRequest->request->get('a');
|
||||
|
||||
$isAllowedToEdit = api_is_allowed_to_edit();
|
||||
|
||||
switch ($action) {
|
||||
case 'get_class_by_keyword':
|
||||
$keyword = $httpRequest->query->has('q') ? $httpRequest->query->get('q') : $httpRequest->request->get('q');
|
||||
$allow = api_is_platform_admin() || api_is_session_admin();
|
||||
|
||||
if ($allow && !empty($keyword)) {
|
||||
$userGroup = new UserGroup();
|
||||
$where = ['where' => ['name like ?' => "%$keyword%"], 'order' => 'name '];
|
||||
$items = [];
|
||||
$list = $userGroup->get_all($where);
|
||||
foreach ($list as $class) {
|
||||
$items[] = [
|
||||
'id' => $class['id'],
|
||||
'text' => $class['name'],
|
||||
];
|
||||
}
|
||||
echo json_encode(['items' => $items]);
|
||||
}
|
||||
break;
|
||||
case 'delete_user_in_usergroup':
|
||||
if ($isAllowedToEdit) {
|
||||
$userGroup = new UserGroup();
|
||||
$userId = $httpRequest->query->has('id')
|
||||
? $httpRequest->query->getInt('id')
|
||||
: $httpRequest->request->getInt('id');
|
||||
$userIdList = explode(',', $userId);
|
||||
$groupId = $httpRequest->query->has('group_id')
|
||||
? $httpRequest->query->getInt('group_id')
|
||||
: $httpRequest->request->getInt('group_id');
|
||||
foreach ($userIdList as $userId) {
|
||||
$userGroup->delete_user_rel_group($userId, $groupId);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
echo '';
|
||||
break;
|
||||
}
|
||||
exit;
|
||||
253
main/inc/ajax/work.ajax.php
Normal file
253
main/inc/ajax/work.ajax.php
Normal file
@@ -0,0 +1,253 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Responses to AJAX calls.
|
||||
*/
|
||||
require_once __DIR__.'/../global.inc.php';
|
||||
require_once api_get_path(SYS_CODE_PATH).'work/work.lib.php';
|
||||
|
||||
$action = isset($_REQUEST['a']) ? $_REQUEST['a'] : null;
|
||||
$isAllowedToEdit = api_is_allowed_to_edit();
|
||||
$courseInfo = api_get_course_info();
|
||||
|
||||
switch ($action) {
|
||||
case 'show_student_work':
|
||||
api_protect_course_script(true);
|
||||
if ($isAllowedToEdit) {
|
||||
$itemList = isset($_REQUEST['item_list']) ? $_REQUEST['item_list'] : [];
|
||||
$itemList = explode(',', $itemList);
|
||||
if (!empty($itemList)) {
|
||||
foreach ($itemList as $itemId) {
|
||||
makeVisible($itemId, $courseInfo);
|
||||
}
|
||||
echo '1';
|
||||
exit;
|
||||
}
|
||||
}
|
||||
echo '0';
|
||||
break;
|
||||
case 'hide_student_work':
|
||||
api_protect_course_script(true);
|
||||
if ($isAllowedToEdit) {
|
||||
$itemList = isset($_REQUEST['item_list']) ? $_REQUEST['item_list'] : [];
|
||||
$itemList = explode(',', $itemList);
|
||||
if (!empty($itemList)) {
|
||||
foreach ($itemList as $itemId) {
|
||||
makeInvisible($itemId, $courseInfo);
|
||||
}
|
||||
echo '1';
|
||||
exit;
|
||||
}
|
||||
}
|
||||
echo '0';
|
||||
break;
|
||||
case 'delete_student_work':
|
||||
api_protect_course_script(true);
|
||||
if ($isAllowedToEdit) {
|
||||
if (empty($_REQUEST['id'])) {
|
||||
return false;
|
||||
}
|
||||
$itemList = explode(',', $_REQUEST['id']);
|
||||
foreach ($itemList as $itemId) {
|
||||
deleteWorkItem($itemId, $courseInfo);
|
||||
}
|
||||
echo '1';
|
||||
exit;
|
||||
}
|
||||
echo '0';
|
||||
break;
|
||||
case 'upload_file':
|
||||
api_protect_course_script(true);
|
||||
|
||||
if (isset($_REQUEST['chunkAction']) && 'send' === $_REQUEST['chunkAction']) {
|
||||
// It uploads the files in chunks
|
||||
if (!empty($_FILES)) {
|
||||
$tempDirectory = api_get_path(SYS_ARCHIVE_PATH);
|
||||
$files = $_FILES['files'];
|
||||
$fileList = [];
|
||||
foreach ($files as $name => $array) {
|
||||
$counter = 0;
|
||||
foreach ($array as $data) {
|
||||
$fileList[$counter][$name] = $data;
|
||||
$counter++;
|
||||
}
|
||||
}
|
||||
if (!empty($fileList)) {
|
||||
foreach ($fileList as $n => $file) {
|
||||
$tmpFile = disable_dangerous_file(
|
||||
api_replace_dangerous_char($file['name'])
|
||||
);
|
||||
|
||||
file_put_contents(
|
||||
$tempDirectory.$tmpFile,
|
||||
fopen($file['tmp_name'], 'r'),
|
||||
FILE_APPEND
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
echo json_encode([
|
||||
'files' => $_FILES,
|
||||
'errorStatus' => 0,
|
||||
]);
|
||||
exit;
|
||||
} else {
|
||||
$workId = isset($_REQUEST['id']) ? $_REQUEST['id'] : '';
|
||||
$workInfo = get_work_data_by_id($workId);
|
||||
$sessionId = api_get_session_id();
|
||||
$userId = api_get_user_id();
|
||||
$groupId = api_get_group_id();
|
||||
|
||||
$onlyOnePublication = api_get_configuration_value('allow_only_one_student_publication_per_user');
|
||||
if ($onlyOnePublication) {
|
||||
$count = get_work_count_by_student($userId, $workId);
|
||||
if ($count >= 1) {
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($_FILES)) {
|
||||
$files = $_FILES['files'];
|
||||
$fileList = [];
|
||||
foreach ($files as $name => $array) {
|
||||
$counter = 0;
|
||||
foreach ($array as $data) {
|
||||
$fileList[$counter][$name] = $data;
|
||||
$counter++;
|
||||
}
|
||||
}
|
||||
|
||||
$resultList = [];
|
||||
foreach ($fileList as $fileInfo) {
|
||||
$file = processChunkedFile($fileInfo);
|
||||
|
||||
$globalFile = [];
|
||||
$globalFile['files'] = $file;
|
||||
|
||||
$values = [
|
||||
'contains_file' => 1,
|
||||
'title' => $file['name'],
|
||||
'description' => '',
|
||||
];
|
||||
|
||||
$result = processWorkForm(
|
||||
$workInfo,
|
||||
$values,
|
||||
$courseInfo,
|
||||
$sessionId,
|
||||
$groupId,
|
||||
$userId,
|
||||
$file,
|
||||
api_get_configuration_value('assignment_prevent_duplicate_upload'),
|
||||
false
|
||||
);
|
||||
|
||||
$json = [];
|
||||
if (!empty($result) && is_array($result) && empty($result['error'])) {
|
||||
$json['name'] = api_htmlentities($result['title']);
|
||||
$json['link'] = Display::url(
|
||||
api_htmlentities($result['title']),
|
||||
api_htmlentities($result['view_url']),
|
||||
['target' => '_blank']
|
||||
);
|
||||
|
||||
$json['url'] = $result['view_url'];
|
||||
$json['size'] = '';
|
||||
$json['type'] = api_htmlentities($result['filetype']);
|
||||
$json['result'] = Display::return_icon(
|
||||
'accept.png',
|
||||
get_lang('Uploaded')
|
||||
);
|
||||
} else {
|
||||
$json['url'] = '';
|
||||
$json['error'] = isset($result['error']) ? $result['error'] : get_lang('Error');
|
||||
}
|
||||
$resultList[] = $json;
|
||||
}
|
||||
|
||||
echo json_encode(['files' => $resultList]);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'delete_work':
|
||||
if ($isAllowedToEdit) {
|
||||
if (empty($_REQUEST['id'])) {
|
||||
return false;
|
||||
}
|
||||
$workList = explode(',', $_REQUEST['id']);
|
||||
foreach ($workList as $workId) {
|
||||
deleteDirWork($workId);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'upload_correction_file':
|
||||
api_protect_course_script(true);
|
||||
// User access same as upload.php
|
||||
$is_allowed_to_edit = api_is_allowed_to_edit(null, true);
|
||||
$itemId = isset($_GET['item_id']) ? (int) $_GET['item_id'] : '';
|
||||
$result = [];
|
||||
if (!empty($_FILES) && !empty($itemId)) {
|
||||
$file = $_FILES['file'];
|
||||
$courseInfo = api_get_course_info();
|
||||
$workInfo = get_work_data_by_id($itemId);
|
||||
$workInfoParent = get_work_data_by_id($workInfo['parent_id']);
|
||||
$resultUpload = uploadWork($workInfoParent, $courseInfo, true, $workInfo);
|
||||
if (!$resultUpload) {
|
||||
echo 'false';
|
||||
break;
|
||||
}
|
||||
$work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
|
||||
|
||||
if (isset($resultUpload['url']) && !empty($resultUpload['url'])) {
|
||||
$title = isset($resultUpload['filename']) && !empty($resultUpload['filename']) ? $resultUpload['filename'] : get_lang('Untitled');
|
||||
$url = Database::escape_string($resultUpload['url']);
|
||||
$title = Database::escape_string($title);
|
||||
|
||||
$sql = "UPDATE $work_table SET
|
||||
url_correction = '".$url."',
|
||||
title_correction = '".$title."'
|
||||
WHERE iid = $itemId";
|
||||
Database::query($sql);
|
||||
|
||||
$result['title'] = $resultUpload['filename'];
|
||||
$result['url'] = 'view.php?'.api_get_cidreq().'&id='.$itemId;
|
||||
|
||||
$json = [];
|
||||
$json['name'] = Display::url(
|
||||
api_htmlentities($result['title']),
|
||||
api_htmlentities($result['url']),
|
||||
['target' => '_blank']
|
||||
);
|
||||
|
||||
$json['type'] = api_htmlentities($file['type']);
|
||||
$json['size'] = format_file_size($file['size']);
|
||||
}
|
||||
|
||||
if (isset($result['url'])) {
|
||||
$json['result'] = Display::return_icon(
|
||||
'accept.png',
|
||||
get_lang('Uploaded'),
|
||||
[],
|
||||
ICON_SIZE_TINY
|
||||
);
|
||||
} else {
|
||||
$json['result'] = Display::return_icon(
|
||||
'exclamation.png',
|
||||
get_lang('Error'),
|
||||
[],
|
||||
ICON_SIZE_TINY
|
||||
);
|
||||
}
|
||||
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode($json);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
echo '';
|
||||
break;
|
||||
}
|
||||
exit;
|
||||
119
main/inc/email_editor.php
Normal file
119
main/inc/email_editor.php
Normal file
@@ -0,0 +1,119 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use ChamiloSession as Session;
|
||||
|
||||
/**
|
||||
* This script contains the code to edit and send an e-mail to one of
|
||||
* the platform's users.
|
||||
* It can be called from the JavaScript library email_links.lib.php which
|
||||
* overtakes the mailto: links to use the internal interface instead.
|
||||
*
|
||||
* @author Yannick Warnier <ywarnier@beeznest.org>
|
||||
* @author Julio Montoya <gugli100@gmail.com> Updating form with formvalidator
|
||||
*/
|
||||
require_once __DIR__.'/../inc/global.inc.php';
|
||||
|
||||
if (empty(api_get_user_id()) || ("true" !== api_get_setting('allow_email_editor'))) {
|
||||
api_not_allowed(true);
|
||||
}
|
||||
|
||||
$_user = api_get_user_info();
|
||||
|
||||
$originUrl = Session::read('origin_url');
|
||||
if (empty($originUrl)) {
|
||||
Session::write('origin_url', $_SERVER['HTTP_REFERER']);
|
||||
}
|
||||
|
||||
$action = isset($_GET['action']) ? $_GET['action'] : null;
|
||||
|
||||
$form = new FormValidator('email_editor', 'post');
|
||||
$form->addElement('hidden', 'dest');
|
||||
$form->addElement('text', 'email_address', get_lang('EmailDestination'));
|
||||
$form->addElement('text', 'email_title', get_lang('EmailTitle'));
|
||||
$form->freeze('email_address');
|
||||
$form->addElement('textarea', 'email_text', get_lang('EmailText'), ['rows' => '6']);
|
||||
$form->addRule('email_address', get_lang('ThisFieldIsRequired'), 'required');
|
||||
$form->addRule('email_title', get_lang('ThisFieldIsRequired'), 'required');
|
||||
$form->addRule('email_text', get_lang('ThisFieldIsRequired'), 'required');
|
||||
$form->addRule('email_address', get_lang('EmailWrong'), 'email');
|
||||
$form->addButtonSend(get_lang('SendMail'));
|
||||
|
||||
switch ($action) {
|
||||
case 'subscribe_me_to_session':
|
||||
$sessionName = isset($_GET['session']) ? Security::remove_XSS($_GET['session']) : null;
|
||||
|
||||
$objTemplate = new Template();
|
||||
$objTemplate->assign('session_name', $sessionName);
|
||||
$objTemplate->assign('user', api_get_user_info(api_get_user_id(), false, false, true));
|
||||
$mailTemplate = $objTemplate->get_template('mail/subscribe_me_to_session.tpl');
|
||||
|
||||
$emailDest = api_get_setting('emailAdministrator');
|
||||
$emailTitle = get_lang('SubscribeToSessionRequest');
|
||||
$emailText = $objTemplate->fetch($mailTemplate);
|
||||
break;
|
||||
default:
|
||||
$emailDest = isset($_REQUEST['dest']) ? Security::remove_XSS($_REQUEST['dest']) : '';
|
||||
$emailTitle = isset($_REQUEST['subject']) ? Security::remove_XSS($_REQUEST['subject']) : '';
|
||||
$emailText = isset($_REQUEST['body']) ? Security::remove_XSS($_REQUEST['body']) : '';
|
||||
break;
|
||||
}
|
||||
|
||||
$defaults = [
|
||||
'dest' => $emailDest,
|
||||
'email_address' => $emailDest,
|
||||
'email_title' => $emailTitle,
|
||||
'email_text' => $emailText,
|
||||
];
|
||||
$form->setDefaults($defaults);
|
||||
|
||||
if ($form->validate()) {
|
||||
$check = Security::check_token();
|
||||
Security::clear_token();
|
||||
if ($check) {
|
||||
Security::clear_token();
|
||||
$values = $form->getSubmitValues();
|
||||
$text = nl2br($values['email_text']).'<br /><br /><br />'.get_lang('EmailSentFromLMS').' '.api_get_path(
|
||||
WEB_PATH
|
||||
);
|
||||
$email_administrator = $values['dest'];
|
||||
$title = $values['email_title'];
|
||||
|
||||
if (!empty($_user['mail'])) {
|
||||
api_mail_html(
|
||||
'',
|
||||
$email_administrator,
|
||||
$title,
|
||||
$text,
|
||||
api_get_person_name($_user['firstname'], $_user['lastname']),
|
||||
$_user['mail'],
|
||||
[
|
||||
'reply_to' => [
|
||||
'mail' => $_user['mail'],
|
||||
'name' => api_get_person_name($_user['firstname'], $_user['lastname']),
|
||||
],
|
||||
]
|
||||
);
|
||||
} else {
|
||||
api_mail_html(
|
||||
'',
|
||||
$email_administrator,
|
||||
$title,
|
||||
$text,
|
||||
get_lang('Anonymous')
|
||||
);
|
||||
}
|
||||
|
||||
Display::addFlash(Display::return_message(get_lang('MessageSent')));
|
||||
$orig = Session::read('origin_url');
|
||||
Session::erase('origin_url');
|
||||
header('Location:'.$orig);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
$form->addHidden('sec_token', Security::get_token());
|
||||
|
||||
Display::display_header(get_lang('SendEmail'));
|
||||
$form->display();
|
||||
Display::display_footer();
|
||||
72
main/inc/email_editor_external.php
Normal file
72
main/inc/email_editor_external.php
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use ChamiloSession as Session;
|
||||
|
||||
/**
|
||||
* This script contains the code to send an e-mail to the portal admin.
|
||||
*/
|
||||
require_once __DIR__.'/../inc/global.inc.php';
|
||||
|
||||
if (false === api_get_configuration_value('allow_email_editor_for_anonymous')) {
|
||||
api_not_allowed(true);
|
||||
}
|
||||
|
||||
$originUrl = Session::read('origin_url');
|
||||
if (empty($originUrl) && isset($_SERVER['HTTP_REFERER'])) {
|
||||
Session::write('origin_url', $_SERVER['HTTP_REFERER']);
|
||||
}
|
||||
|
||||
$action = isset($_GET['action']) ? $_GET['action'] : null;
|
||||
|
||||
$form = new FormValidator('email_editor', 'post');
|
||||
$form->addText('email', get_lang('Email'));
|
||||
$form->addRule('email', get_lang('EmailWrong'), 'email');
|
||||
$form->addText('email_title', get_lang('EmailTitle'));
|
||||
$form->addTextarea('email_text', get_lang('Message'), ['rows' => '6'], true);
|
||||
$form->addCaptcha();
|
||||
$form->addButtonSend(get_lang('SendMail'));
|
||||
|
||||
$emailTitle = isset($_REQUEST['subject']) ? Security::remove_XSS($_REQUEST['subject']) : '';
|
||||
$emailText = isset($_REQUEST['body']) ? Security::remove_XSS($_REQUEST['body']) : '';
|
||||
|
||||
$defaults = [
|
||||
'email_title' => $emailTitle,
|
||||
'email_text' => $emailText,
|
||||
];
|
||||
|
||||
if (isset($_POST)) {
|
||||
$defaults = [
|
||||
'email' => $_REQUEST['email'] ?? null,
|
||||
'email_title' => $_REQUEST['email_title'] ?? null,
|
||||
'email_text' => $_REQUEST['email_text'] ?? null,
|
||||
];
|
||||
}
|
||||
|
||||
$form->setDefaults($defaults);
|
||||
if ($form->validate()) {
|
||||
$values = $form->getSubmitValues();
|
||||
$message =
|
||||
get_lang('Sender').': '.$values['email'].'<br /><br />'.
|
||||
nl2br($values['email_text']).
|
||||
'<br /><br /><br />'.get_lang('EmailSentFromLMS').' '.api_get_path(WEB_PATH);
|
||||
|
||||
api_mail_html(
|
||||
'',
|
||||
api_get_setting('emailAdministrator'),
|
||||
$values['email_title'],
|
||||
$message,
|
||||
get_lang('Anonymous')
|
||||
);
|
||||
|
||||
Display::addFlash(Display::return_message(get_lang('MessageSent')));
|
||||
$orig = Session::read('origin_url');
|
||||
Session::erase('origin_url');
|
||||
header('Location:'.$orig);
|
||||
exit;
|
||||
}
|
||||
|
||||
Display::display_header(get_lang('SendEmail'));
|
||||
$form->display();
|
||||
Display::display_footer();
|
||||
336
main/inc/global-min.inc.php
Normal file
336
main/inc/global-min.inc.php
Normal file
@@ -0,0 +1,336 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
/**
|
||||
* This is a minified version of global.inc.php meant *only* for download.php
|
||||
* to check permissions and deliver the file.
|
||||
*/
|
||||
|
||||
// Include the libraries that are necessary everywhere
|
||||
require_once __DIR__.'/../../vendor/autoload.php';
|
||||
require_once __DIR__.'/../../app/AppKernel.php';
|
||||
|
||||
$kernel = new AppKernel('', '');
|
||||
|
||||
// Determine the directory path where this current file lies.
|
||||
// This path will be useful to include the other initialisation files.
|
||||
$includePath = __DIR__;
|
||||
|
||||
// Include the main Chamilo platform configuration file.
|
||||
|
||||
$_configuration = [];
|
||||
$alreadyInstalled = false;
|
||||
if (file_exists($kernel->getConfigurationFile())) {
|
||||
require_once $kernel->getConfigurationFile();
|
||||
$alreadyInstalled = true;
|
||||
// Recalculate a system absolute path symlinks insensible.
|
||||
$includePath = $_configuration['root_sys'].'main/inc/';
|
||||
} else {
|
||||
//Redirects to the main/install/ page
|
||||
if (!$alreadyInstalled) {
|
||||
$global_error_code = 2;
|
||||
// The system has not been installed yet.
|
||||
require_once __DIR__.'/../inc/global_error_message.inc.php';
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
$kernel->setApi($_configuration);
|
||||
|
||||
// Ensure that _configuration is in the global scope before loading
|
||||
// main_api.lib.php. This is particularly helpful for unit tests
|
||||
if (!isset($GLOBALS['_configuration'])) {
|
||||
$GLOBALS['_configuration'] = $_configuration;
|
||||
}
|
||||
|
||||
// Include the main Chamilo platform library file.
|
||||
require_once $_configuration['root_sys'].'main/inc/lib/api.lib.php';
|
||||
|
||||
// Fix bug in IIS that doesn't fill the $_SERVER['REQUEST_URI'].
|
||||
api_request_uri();
|
||||
|
||||
// Do not over-use this variable. It is only for this script's local use.
|
||||
$libraryPath = __DIR__.'/lib/';
|
||||
|
||||
// @todo convert this libs in classes
|
||||
require_once $libraryPath.'database.constants.inc.php';
|
||||
require_once $libraryPath.'text.lib.php';
|
||||
require_once $libraryPath.'array.lib.php';
|
||||
require_once $libraryPath.'online.inc.php';
|
||||
require_once $libraryPath.'banner.lib.php';
|
||||
|
||||
// Doctrine ORM configuration
|
||||
|
||||
$dbParams = [
|
||||
'driver' => 'pdo_mysql',
|
||||
'host' => $_configuration['db_host'],
|
||||
'user' => $_configuration['db_user'],
|
||||
'password' => $_configuration['db_password'],
|
||||
'dbname' => $_configuration['main_database'],
|
||||
// Only relevant for pdo_sqlite, specifies the path to the SQLite database.
|
||||
'path' => isset($_configuration['db_path']) ? $_configuration['db_path'] : '',
|
||||
// Only relevant for pdo_mysql, pdo_pgsql, and pdo_oci/oci8,
|
||||
'port' => isset($_configuration['db_port']) ? $_configuration['db_port'] : '',
|
||||
];
|
||||
|
||||
try {
|
||||
$database = new \Database();
|
||||
$database->connect($dbParams);
|
||||
} catch (Exception $e) {
|
||||
$global_error_code = 3;
|
||||
// The database server is not available or credentials are invalid.
|
||||
require $includePath.'/global_error_message.inc.php';
|
||||
exit();
|
||||
}
|
||||
|
||||
/* RETRIEVING ALL THE CHAMILO CONFIG SETTINGS FOR MULTIPLE URLs FEATURE*/
|
||||
if (!empty($_configuration['multiple_access_urls'])) {
|
||||
$_configuration['access_url'] = 1;
|
||||
$access_urls = api_get_access_urls();
|
||||
$root_rel = api_get_self();
|
||||
$root_rel = substr($root_rel, 1);
|
||||
$pos = strpos($root_rel, '/');
|
||||
$root_rel = substr($root_rel, 0, $pos);
|
||||
$protocol = 'http://';
|
||||
if (!empty($_SERVER['HTTPS']) && strtoupper($_SERVER['HTTPS']) != 'OFF') {
|
||||
$protocol = 'https://';
|
||||
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') {
|
||||
$protocol = 'https://';
|
||||
}
|
||||
|
||||
//urls with subdomains (HTTP_HOST is preferred - see #6764)
|
||||
$request_url_root = '';
|
||||
if (empty($_SERVER['HTTP_HOST'])) {
|
||||
if (empty($_SERVER['SERVER_NAME'])) {
|
||||
$request_url_root = $protocol.'localhost/';
|
||||
} else {
|
||||
$request_url_root = $protocol.$_SERVER['SERVER_NAME'].'/';
|
||||
}
|
||||
} else {
|
||||
$request_url_root = $protocol.$_SERVER['HTTP_HOST'].'/';
|
||||
}
|
||||
//urls with subdirs
|
||||
$request_url_sub = $request_url_root.$root_rel.'/';
|
||||
|
||||
// You can use subdirs as multi-urls, but in this case none of them can be
|
||||
// the root dir. The admin portal should be something like https://host/adm/
|
||||
// At this time, subdirs will still hold a share cookie, so not ideal yet
|
||||
// see #6510
|
||||
foreach ($access_urls as $details) {
|
||||
if ($request_url_sub == $details['url']) {
|
||||
$_configuration['access_url'] = $details['id'];
|
||||
break; //found one match with subdir, get out of foreach
|
||||
}
|
||||
// Didn't find any? Now try without subdirs
|
||||
if ($request_url_root == $details['url']) {
|
||||
$_configuration['access_url'] = $details['id'];
|
||||
break; //found one match, get out of foreach
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$_configuration['access_url'] = 1;
|
||||
}
|
||||
|
||||
// Check if APCu is available. If so, store the value in $_configuration
|
||||
if (extension_loaded('apcu')) {
|
||||
$apcEnabled = ini_get('apc.enabled');
|
||||
if (!empty($apcEnabled) && $apcEnabled != 'Off' && $apcEnabled != 'off') {
|
||||
$_configuration['apc'] = true;
|
||||
$_configuration['apc_prefix'] = $_configuration['main_database'].'_'.$_configuration['access_url'].'_';
|
||||
}
|
||||
}
|
||||
|
||||
$charset = 'UTF-8';
|
||||
|
||||
// Enables the portability layer and configures PHP for UTF-8
|
||||
\Patchwork\Utf8\Bootup::initAll();
|
||||
|
||||
// Start session after the internationalization library has been initialized.
|
||||
ChamiloSession::start($alreadyInstalled);
|
||||
|
||||
// access_url == 1 is the default chamilo location
|
||||
if ($_configuration['access_url'] != 1) {
|
||||
$url_info = api_get_access_url($_configuration['access_url']);
|
||||
if ($url_info['active'] == 1) {
|
||||
$settings_by_access = api_get_settings(null, 'list', $_configuration['access_url'], 1);
|
||||
foreach ($settings_by_access as &$row) {
|
||||
if (empty($row['variable'])) {
|
||||
$row['variable'] = 0;
|
||||
}
|
||||
if (empty($row['subkey'])) {
|
||||
$row['subkey'] = 0;
|
||||
}
|
||||
if (empty($row['category'])) {
|
||||
$row['category'] = 0;
|
||||
}
|
||||
$settings_by_access_list[$row['variable']][$row['subkey']][$row['category']] = $row;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$result = api_get_settings(null, 'list', 1);
|
||||
foreach ($result as &$row) {
|
||||
if ($_configuration['access_url'] != 1) {
|
||||
if ($url_info['active'] == 1) {
|
||||
$var = empty($row['variable']) ? 0 : $row['variable'];
|
||||
$subkey = empty($row['subkey']) ? 0 : $row['subkey'];
|
||||
$category = empty($row['category']) ? 0 : $row['category'];
|
||||
}
|
||||
|
||||
if ($row['access_url_changeable'] == 1 && $url_info['active'] == 1) {
|
||||
if (isset($settings_by_access_list[$var]) &&
|
||||
isset($settings_by_access_list[$var][$subkey]) &&
|
||||
$settings_by_access_list[$var][$subkey][$category]['selected_value'] != '') {
|
||||
if ($row['subkey'] == null) {
|
||||
$_setting[$row['variable']] = $settings_by_access_list[$var][$subkey][$category]['selected_value'];
|
||||
} else {
|
||||
$_setting[$row['variable']][$row['subkey']] = $settings_by_access_list[$var][$subkey][$category]['selected_value'];
|
||||
}
|
||||
} else {
|
||||
if ($row['subkey'] == null) {
|
||||
$_setting[$row['variable']] = $row['selected_value'];
|
||||
} else {
|
||||
$_setting[$row['variable']][$row['subkey']] = $row['selected_value'];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ($row['subkey'] == null) {
|
||||
$_setting[$row['variable']] = $row['selected_value'];
|
||||
} else {
|
||||
$_setting[$row['variable']][$row['subkey']] = $row['selected_value'];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ($row['subkey'] == null) {
|
||||
$_setting[$row['variable']] = $row['selected_value'];
|
||||
} else {
|
||||
$_setting[$row['variable']][$row['subkey']] = $row['selected_value'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$result = api_get_settings('Plugins', 'list', $_configuration['access_url']);
|
||||
$_plugins = [];
|
||||
foreach ($result as &$row) {
|
||||
$key = &$row['variable'];
|
||||
if (isset($_setting[$key]) && is_string($_setting[$key])) {
|
||||
$_setting[$key] = [];
|
||||
}
|
||||
if ($row['subkey'] == null) {
|
||||
$_setting[$key][] = $row['selected_value'];
|
||||
$_plugins[$key][] = $row['selected_value'];
|
||||
} else {
|
||||
$_setting[$key][$row['subkey']] = $row['selected_value'];
|
||||
$_plugins[$key][$row['subkey']] = $row['selected_value'];
|
||||
}
|
||||
}
|
||||
|
||||
ini_set('log_errors', '1');
|
||||
|
||||
/**
|
||||
* Include the trad4all language file.
|
||||
*/
|
||||
// if we use the javascript version (without go button) we receive a get
|
||||
// if we use the non-javascript version (with the go button) we receive a post
|
||||
$user_language = '';
|
||||
$browser_language = '';
|
||||
|
||||
// see #8149
|
||||
if (!empty($_SESSION['user_language_choice'])) {
|
||||
$user_language = $_SESSION['user_language_choice'];
|
||||
}
|
||||
|
||||
if (!empty($_GET['language'])) {
|
||||
$user_language = $_GET['language'];
|
||||
}
|
||||
|
||||
if (!empty($_POST['language_list'])) {
|
||||
$user_language = preg_replace('/index\.php\?language=/', '', $_POST['language_list']);
|
||||
}
|
||||
|
||||
if (empty($user_language) && !empty($_SERVER['HTTP_ACCEPT_LANGUAGE']) && !isset($_SESSION['_user'])) {
|
||||
$l = SubLanguageManager::getLanguageFromBrowserPreference($_SERVER['HTTP_ACCEPT_LANGUAGE']);
|
||||
if (!empty($l)) {
|
||||
$user_language = $browser_language = $l;
|
||||
}
|
||||
}
|
||||
// Checking if we have a valid language. If not we set it to the platform language.
|
||||
$valid_languages = api_get_languages();
|
||||
|
||||
if (!empty($valid_languages)) {
|
||||
if (!in_array($user_language, $valid_languages['folder'])) {
|
||||
$user_language = api_get_setting('platformLanguage');
|
||||
}
|
||||
|
||||
$language_priority1 = api_get_setting('languagePriority1');
|
||||
$language_priority2 = api_get_setting('languagePriority2');
|
||||
$language_priority3 = api_get_setting('languagePriority3');
|
||||
$language_priority4 = api_get_setting('languagePriority4');
|
||||
|
||||
if (isset($_GET['language']) ||
|
||||
(isset($_POST['language_list']) && !empty($_POST['language_list'])) ||
|
||||
!empty($browser_language)
|
||||
) {
|
||||
$user_selected_language = $user_language; // $_GET['language']; or HTTP_ACCEPT_LANGUAGE
|
||||
$_SESSION['user_language_choice'] = $user_selected_language;
|
||||
$platformLanguage = $user_selected_language;
|
||||
}
|
||||
|
||||
if (!empty($language_priority4) && api_get_language_from_type($language_priority4) !== false) {
|
||||
$language_interface = api_get_language_from_type($language_priority4);
|
||||
} else {
|
||||
$language_interface = api_get_setting('platformLanguage');
|
||||
}
|
||||
|
||||
if (!empty($language_priority3) && api_get_language_from_type($language_priority3) !== false) {
|
||||
$language_interface = api_get_language_from_type($language_priority3);
|
||||
} else {
|
||||
if (isset($_SESSION['user_language_choice'])) {
|
||||
$language_interface = $_SESSION['user_language_choice'];
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($language_priority2) && api_get_language_from_type($language_priority2) !== false) {
|
||||
$language_interface = api_get_language_from_type($language_priority2);
|
||||
} else {
|
||||
if (isset($_user['language'])) {
|
||||
$language_interface = $_user['language'];
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($language_priority1) && api_get_language_from_type($language_priority1) !== false) {
|
||||
$language_interface = api_get_language_from_type($language_priority1);
|
||||
} else {
|
||||
if (isset($_course['language'])) {
|
||||
$language_interface = $_course['language'];
|
||||
}
|
||||
}
|
||||
|
||||
// If language is set via browser ignore the priority
|
||||
if (isset($_GET['language'])) {
|
||||
$language_interface = $user_language;
|
||||
}
|
||||
}
|
||||
|
||||
$language_interface_initial_value = $language_interface;
|
||||
|
||||
$langPath = api_get_path(SYS_LANG_PATH);
|
||||
$languageFilesToLoad = [
|
||||
$langPath.'english/trad4all.inc.php',
|
||||
$langPath.$language_interface.'/trad4all.inc.php',
|
||||
];
|
||||
|
||||
foreach ($languageFilesToLoad as $languageFile) {
|
||||
if (is_file($languageFile)) {
|
||||
require $languageFile;
|
||||
}
|
||||
}
|
||||
|
||||
// include the local (contextual) parameters of this course or section
|
||||
require $includePath.'/local.inc.php';
|
||||
|
||||
// Update of the logout_date field in the table track_e_login
|
||||
// (needed for the calculation of the total connection time)
|
||||
if (!isset($_SESSION['login_as']) && isset($_user) && isset($_user["user_id"])) {
|
||||
// if $_SESSION['login_as'] is set, then the user is an admin logged as the user
|
||||
Tracking::updateUserLastLogin($_user["user_id"]);
|
||||
}
|
||||
641
main/inc/global.inc.php
Normal file
641
main/inc/global.inc.php
Normal file
@@ -0,0 +1,641 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use Chamilo\CoreBundle\Component\Utils\ChamiloApi;
|
||||
|
||||
/**
|
||||
* It is recommended that ALL Chamilo scripts include this important file.
|
||||
* This script manages
|
||||
* - include of /app/config/configuration.php;
|
||||
* - include of several libraries: api, database, display, text, security;
|
||||
* - selecting the main database;
|
||||
* - include of language files.
|
||||
*
|
||||
* @package chamilo.include
|
||||
*
|
||||
* @todo remove the code that displays the button that links to the install page
|
||||
* but use a redirect immediately. By doing so the $alreadyInstalled variable can be removed.
|
||||
*/
|
||||
define('SHOW_ERROR_CODES', false);
|
||||
|
||||
// Include the libraries that are necessary everywhere
|
||||
require_once __DIR__.'/../../vendor/autoload.php';
|
||||
require_once __DIR__.'/../../app/AppKernel.php';
|
||||
|
||||
$kernel = new AppKernel('', '');
|
||||
|
||||
// Determine the directory path where this current file lies.
|
||||
// This path will be useful to include the other initialisation files.
|
||||
$includePath = __DIR__;
|
||||
|
||||
// Include the main Chamilo platform configuration file.
|
||||
|
||||
$alreadyInstalled = false;
|
||||
if (file_exists($kernel->getConfigurationFile())) {
|
||||
require_once $kernel->getConfigurationFile();
|
||||
$alreadyInstalled = true;
|
||||
// Recalculate a system absolute path symlinks insensible.
|
||||
$includePath = $_configuration['root_sys'].'main/inc/';
|
||||
} else {
|
||||
$_configuration = [];
|
||||
//Redirects to the main/install/ page
|
||||
if (!$alreadyInstalled) {
|
||||
$global_error_code = 2;
|
||||
// The system has not been installed yet.
|
||||
require_once __DIR__.'/../inc/global_error_message.inc.php';
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
$kernel->setApi($_configuration);
|
||||
|
||||
// Ensure that _configuration is in the global scope before loading
|
||||
// main_api.lib.php. This is particularly helpful for unit tests
|
||||
if (!isset($GLOBALS['_configuration'])) {
|
||||
$GLOBALS['_configuration'] = $_configuration;
|
||||
}
|
||||
|
||||
// Include the main Chamilo platform library file.
|
||||
require_once $_configuration['root_sys'].'main/inc/lib/api.lib.php';
|
||||
$passwordEncryption = api_get_configuration_value('password_encryption');
|
||||
|
||||
if ($passwordEncryption === 'bcrypt') {
|
||||
require_once __DIR__.'/../../vendor/ircmaxell/password-compat/lib/password.php';
|
||||
}
|
||||
|
||||
// Check the PHP version
|
||||
api_check_php_version($includePath.'/');
|
||||
|
||||
// Fix bug in IIS that doesn't fill the $_SERVER['REQUEST_URI'].
|
||||
api_request_uri();
|
||||
|
||||
// Set web proxy environment variables
|
||||
foreach ([
|
||||
'proxy_settings/stream_context_create/https/proxy',
|
||||
'proxy_settings/stream_context_create/http/proxy',
|
||||
'proxy_settings/curl_setopt_array/CURLOPT_PROXY',
|
||||
] as $path) {
|
||||
$value = api_get_configuration_sub_value($path);
|
||||
if (!empty($value) && is_string($value)) {
|
||||
// libcurl reads environment variable https_proxy: https://curl.haxx.se/libcurl/c/libcurl-env.html
|
||||
// \GuzzleHttp\Client::configureDefaults reads environment variable HTTPS_PROXY
|
||||
foreach (['https_proxy', 'http_proxy', 'HTTPS_PROXY', 'HTTP_PROXY'] as $envVar) {
|
||||
if (false === getenv($envVar)) {
|
||||
putenv("$envVar=$value");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
define('_MPDF_TEMP_PATH', __DIR__.'/../../app/cache/mpdf/');
|
||||
define('_MPDF_TTFONTDATAPATH', __DIR__.'/../../app/cache/mpdf/');
|
||||
|
||||
// Include the libraries that are necessary everywhere
|
||||
require_once __DIR__.'/../../vendor/autoload.php';
|
||||
|
||||
// Do not over-use this variable. It is only for this script's local use.
|
||||
$libraryPath = __DIR__.'/lib/';
|
||||
|
||||
// @todo convert this libs in classes
|
||||
require_once $libraryPath.'database.constants.inc.php';
|
||||
require_once $libraryPath.'formvalidator/FormValidator.class.php';
|
||||
require_once $libraryPath.'text.lib.php';
|
||||
require_once $libraryPath.'array.lib.php';
|
||||
require_once $libraryPath.'online.inc.php';
|
||||
require_once $libraryPath.'banner.lib.php';
|
||||
require_once $libraryPath.'fileManage.lib.php';
|
||||
require_once $libraryPath.'fileUpload.lib.php';
|
||||
require_once $libraryPath.'fileDisplay.lib.php';
|
||||
require_once $libraryPath.'course_category.lib.php';
|
||||
|
||||
if (!is_dir(_MPDF_TEMP_PATH)) {
|
||||
mkdir(_MPDF_TEMP_PATH, api_get_permissions_for_new_directories(), true);
|
||||
}
|
||||
|
||||
// Connect to the server database and select the main chamilo database.
|
||||
// When $_configuration['db_persistent_connection'] is set, it is expected to be a boolean type.
|
||||
/*$dbPersistConnection = api_get_configuration_value('db_persistent_connection');
|
||||
// $_configuration['db_client_flags'] can be set in configuration.php to pass
|
||||
// flags to the DB connection
|
||||
$dbFlags = api_get_configuration_value('db_client_flags');
|
||||
|
||||
$params = array(
|
||||
'server' => $_configuration['db_host'],
|
||||
'username' => $_configuration['db_user'],
|
||||
'password' => $_configuration['db_password'],
|
||||
'persistent' => $dbPersistConnection,
|
||||
'client_flags' => $dbFlags,
|
||||
);*/
|
||||
|
||||
// Doctrine ORM configuration
|
||||
|
||||
$dbParams = [
|
||||
'driver' => 'pdo_mysql',
|
||||
'host' => $_configuration['db_host'],
|
||||
'user' => $_configuration['db_user'],
|
||||
'password' => $_configuration['db_password'],
|
||||
'dbname' => $_configuration['main_database'],
|
||||
// Only relevant for pdo_sqlite, specifies the path to the SQLite database.
|
||||
'path' => isset($_configuration['db_path']) ? $_configuration['db_path'] : '',
|
||||
// Only relevant for pdo_mysql, pdo_pgsql, and pdo_oci/oci8,
|
||||
'port' => isset($_configuration['db_port']) ? $_configuration['db_port'] : '',
|
||||
'driverOptions' => isset($_configuration['db_client_flags']) && is_array($_configuration['db_client_flags']) ? $_configuration['db_client_flags'] : [],
|
||||
];
|
||||
|
||||
try {
|
||||
$database = new \Database();
|
||||
$database->connect($dbParams);
|
||||
} catch (Exception $e) {
|
||||
$global_error_code = 3;
|
||||
// The database server is not available or credentials are invalid.
|
||||
require $includePath.'/global_error_message.inc.php';
|
||||
exit();
|
||||
}
|
||||
|
||||
/* RETRIEVING ALL THE CHAMILO CONFIG SETTINGS FOR MULTIPLE URLs FEATURE*/
|
||||
if (!empty($_configuration['multiple_access_urls'])) {
|
||||
$_configuration['access_url'] = 1;
|
||||
$access_urls = api_get_access_urls();
|
||||
$root_rel = api_get_self();
|
||||
$root_rel = substr($root_rel, 1);
|
||||
$pos = strpos($root_rel, '/');
|
||||
$root_rel = substr($root_rel, 0, $pos);
|
||||
$protocol = 'http://';
|
||||
if (!empty($_SERVER['HTTPS']) && strtoupper($_SERVER['HTTPS']) != 'OFF') {
|
||||
$protocol = 'https://';
|
||||
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') {
|
||||
$protocol = 'https://';
|
||||
}
|
||||
|
||||
//urls with subdomains (HTTP_HOST is preferred - see #6764)
|
||||
$request_url_root = '';
|
||||
if (empty($_SERVER['HTTP_HOST'])) {
|
||||
if (empty($_SERVER['SERVER_NAME'])) {
|
||||
$request_url_root = $protocol.'localhost/';
|
||||
} else {
|
||||
$request_url_root = $protocol.$_SERVER['SERVER_NAME'].'/';
|
||||
}
|
||||
} else {
|
||||
$request_url_root = $protocol.$_SERVER['HTTP_HOST'].'/';
|
||||
}
|
||||
//urls with subdirs
|
||||
$request_url_sub = $request_url_root.$root_rel.'/';
|
||||
|
||||
// You can use subdirs as multi-urls, but in this case none of them can be
|
||||
// the root dir. The admin portal should be something like https://host/adm/
|
||||
// At this time, subdirs will still hold a share cookie, so not ideal yet
|
||||
// see #6510
|
||||
foreach ($access_urls as $details) {
|
||||
if ($request_url_sub == $details['url']) {
|
||||
$_configuration['access_url'] = $details['id'];
|
||||
break; //found one match with subdir, get out of foreach
|
||||
}
|
||||
// Didn't find any? Now try without subdirs
|
||||
if ($request_url_root == $details['url']) {
|
||||
$_configuration['access_url'] = $details['id'];
|
||||
break; //found one match, get out of foreach
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$_configuration['access_url'] = 1;
|
||||
}
|
||||
|
||||
// Check if APCu is available. If so, store the value in $_configuration
|
||||
if (extension_loaded('apcu')) {
|
||||
$apcEnabled = ini_get('apc.enabled');
|
||||
if (!empty($apcEnabled) && $apcEnabled != 'Off' && $apcEnabled != 'off') {
|
||||
$_configuration['apc'] = true;
|
||||
$_configuration['apc_prefix'] = $_configuration['main_database'].'_'.$_configuration['access_url'].'_';
|
||||
}
|
||||
}
|
||||
|
||||
$charset = 'UTF-8';
|
||||
|
||||
// Enables the portability layer and configures PHP for UTF-8
|
||||
\Patchwork\Utf8\Bootup::initAll();
|
||||
|
||||
// Start session after the internationalization library has been initialized.
|
||||
ChamiloSession::start($alreadyInstalled);
|
||||
|
||||
// access_url == 1 is the default chamilo location
|
||||
if ($_configuration['access_url'] != 1) {
|
||||
$url_info = api_get_access_url($_configuration['access_url']);
|
||||
if ($url_info['active'] == 1) {
|
||||
$settings_by_access = api_get_settings(null, 'list', $_configuration['access_url'], 1);
|
||||
foreach ($settings_by_access as &$row) {
|
||||
if (empty($row['variable'])) {
|
||||
$row['variable'] = 0;
|
||||
}
|
||||
if (empty($row['subkey'])) {
|
||||
$row['subkey'] = 0;
|
||||
}
|
||||
if (empty($row['category'])) {
|
||||
$row['category'] = 0;
|
||||
}
|
||||
$settings_by_access_list[$row['variable']][$row['subkey']][$row['category']] = $row;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$result = api_get_settings(null, 'list', 1);
|
||||
foreach ($result as &$row) {
|
||||
if ($_configuration['access_url'] != 1) {
|
||||
if ($url_info['active'] == 1) {
|
||||
$var = empty($row['variable']) ? 0 : $row['variable'];
|
||||
$subkey = empty($row['subkey']) ? 0 : $row['subkey'];
|
||||
$category = empty($row['category']) ? 0 : $row['category'];
|
||||
}
|
||||
|
||||
if ($row['access_url_changeable'] == 1 && $url_info['active'] == 1) {
|
||||
if (isset($settings_by_access_list[$var]) &&
|
||||
isset($settings_by_access_list[$var][$subkey]) &&
|
||||
$settings_by_access_list[$var][$subkey][$category]['selected_value'] != '') {
|
||||
if ($row['subkey'] == null) {
|
||||
$_setting[$row['variable']] = $settings_by_access_list[$var][$subkey][$category]['selected_value'];
|
||||
} else {
|
||||
$_setting[$row['variable']][$row['subkey']] = $settings_by_access_list[$var][$subkey][$category]['selected_value'];
|
||||
}
|
||||
} else {
|
||||
if ($row['subkey'] == null) {
|
||||
$_setting[$row['variable']] = $row['selected_value'];
|
||||
} else {
|
||||
$_setting[$row['variable']][$row['subkey']] = $row['selected_value'];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ($row['subkey'] == null) {
|
||||
$_setting[$row['variable']] = $row['selected_value'];
|
||||
} else {
|
||||
$_setting[$row['variable']][$row['subkey']] = $row['selected_value'];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ($row['subkey'] == null) {
|
||||
$_setting[$row['variable']] = $row['selected_value'];
|
||||
} else {
|
||||
$_setting[$row['variable']][$row['subkey']] = $row['selected_value'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$result = api_get_settings('Plugins', 'list', $_configuration['access_url']);
|
||||
$_plugins = [];
|
||||
foreach ($result as &$row) {
|
||||
$key = &$row['variable'];
|
||||
if (isset($_setting[$key]) && is_string($_setting[$key])) {
|
||||
$_setting[$key] = [];
|
||||
}
|
||||
if ($row['subkey'] == null) {
|
||||
$_setting[$key][] = $row['selected_value'];
|
||||
$_plugins[$key][] = $row['selected_value'];
|
||||
} else {
|
||||
$_setting[$key][$row['subkey']] = $row['selected_value'];
|
||||
$_plugins[$key][$row['subkey']] = $row['selected_value'];
|
||||
}
|
||||
}
|
||||
|
||||
// Error reporting settings.
|
||||
if (api_get_setting('server_type') == 'test') {
|
||||
ini_set('display_errors', '1');
|
||||
ini_set('html_errors', '1');
|
||||
error_reporting(-1);
|
||||
|
||||
if (function_exists('opcache_reset')) {
|
||||
opcache_reset();
|
||||
}
|
||||
} else {
|
||||
error_reporting(E_COMPILE_ERROR | E_ERROR | E_CORE_ERROR);
|
||||
}
|
||||
|
||||
ini_set('log_errors', '1');
|
||||
|
||||
// Specification for usernames:
|
||||
// 1. ASCII-letters, digits, "." (dot), "_" (underscore) are acceptable, 40 characters maximum length.
|
||||
// 2. Empty username is formally valid, but it is reserved for the anonymous user.
|
||||
// 3. Checking the login_is_email portal setting in order to accept 100 chars maximum
|
||||
|
||||
$defaultUserNameLength = 50;
|
||||
if (api_get_setting('login_is_email') == 'true') {
|
||||
$defaultUserNameLength = 100;
|
||||
}
|
||||
define('USERNAME_MAX_LENGTH', $defaultUserNameLength);
|
||||
|
||||
// Load allowed tag definitions for kses and/or HTMLPurifier.
|
||||
require_once $libraryPath.'formvalidator/Rule/allowed_tags.inc.php';
|
||||
|
||||
// Before we call local.inc.php, let's define a global $this_section variable
|
||||
// which will then be usable from the banner and header scripts
|
||||
$this_section = SECTION_GLOBAL;
|
||||
|
||||
// Including configuration files
|
||||
$configurationFiles = [
|
||||
'mail.conf.php',
|
||||
'profile.conf.php',
|
||||
'course_info.conf.php',
|
||||
'add_course.conf.php',
|
||||
'events.conf.php',
|
||||
'auth.conf.php',
|
||||
];
|
||||
|
||||
foreach ($configurationFiles as $file) {
|
||||
$file = api_get_path(CONFIGURATION_PATH).$file;
|
||||
if (file_exists($file)) {
|
||||
require_once $file;
|
||||
}
|
||||
}
|
||||
|
||||
/* LOAD LANGUAGE FILES SECTION */
|
||||
|
||||
// if we use the javascript version (without go button) we receive a get
|
||||
// if we use the non-javascript version (with the go button) we receive a post
|
||||
$user_language = '';
|
||||
$browser_language = '';
|
||||
|
||||
// see #8149
|
||||
if (!empty($_SESSION['user_language_choice'])) {
|
||||
$user_language = $_SESSION['user_language_choice'];
|
||||
}
|
||||
|
||||
if (!empty($_GET['language'])) {
|
||||
$user_language = $_GET['language'];
|
||||
}
|
||||
|
||||
if (!empty($_POST['language_list'])) {
|
||||
$user_language = str_replace('index.php?language=', '', $_POST['language_list']);
|
||||
}
|
||||
|
||||
if (empty($user_language) && !empty($_SERVER['HTTP_ACCEPT_LANGUAGE']) && !isset($_SESSION['_user'])) {
|
||||
$l = SubLanguageManager::getLanguageFromBrowserPreference($_SERVER['HTTP_ACCEPT_LANGUAGE']);
|
||||
if (!empty($l)) {
|
||||
$user_language = $browser_language = $l;
|
||||
}
|
||||
}
|
||||
|
||||
// Include all files (first english and then current interface language)
|
||||
$langpath = api_get_path(SYS_LANG_PATH);
|
||||
|
||||
/* This will only work if we are in the page to edit a sub_language */
|
||||
if (isset($this_script) && $this_script == 'sub_language') {
|
||||
// getting the arrays of files i.e notification, trad4all, etc
|
||||
$language_files_to_load = SubLanguageManager::get_lang_folder_files_list(
|
||||
api_get_path(SYS_LANG_PATH).'english',
|
||||
true
|
||||
);
|
||||
//getting parent info
|
||||
$parent_language = SubLanguageManager::get_all_information_of_language($_REQUEST['id']);
|
||||
//getting sub language info
|
||||
$sub_language = SubLanguageManager::get_all_information_of_language($_REQUEST['sub_language_id']);
|
||||
|
||||
$english_language_array = $parent_language_array = $sub_language_array = [];
|
||||
|
||||
foreach ($language_files_to_load as $language_file_item) {
|
||||
$lang_list_pre = array_keys($GLOBALS);
|
||||
//loading english
|
||||
$path = $langpath.'english/'.$language_file_item.'.inc.php';
|
||||
if (file_exists($path)) {
|
||||
include $path;
|
||||
}
|
||||
|
||||
$lang_list_post = array_keys($GLOBALS);
|
||||
$lang_list_result = array_diff($lang_list_post, $lang_list_pre);
|
||||
unset($lang_list_pre);
|
||||
|
||||
// english language array
|
||||
$english_language_array[$language_file_item] = compact($lang_list_result);
|
||||
|
||||
//cleaning the variables
|
||||
foreach ($lang_list_result as $item) {
|
||||
unset(${$item});
|
||||
}
|
||||
$parent_file = $langpath.$parent_language['dokeos_folder'].'/'.$language_file_item.'.inc.php';
|
||||
|
||||
if (file_exists($parent_file) && is_file($parent_file)) {
|
||||
include_once $parent_file;
|
||||
}
|
||||
// parent language array
|
||||
$parent_language_array[$language_file_item] = compact($lang_list_result);
|
||||
|
||||
//cleaning the variables
|
||||
foreach ($lang_list_result as $item) {
|
||||
unset(${$item});
|
||||
}
|
||||
|
||||
$sub_file = $langpath.$sub_language['dokeos_folder'].'/'.$language_file_item.'.inc.php';
|
||||
if (file_exists($sub_file) && is_file($sub_file)) {
|
||||
include $sub_file;
|
||||
}
|
||||
|
||||
// sub language array
|
||||
$sub_language_array[$language_file_item] = compact($lang_list_result);
|
||||
|
||||
//cleaning the variables
|
||||
foreach ($lang_list_result as $item) {
|
||||
unset(${$item});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Checking if we have a valid language. If not we set it to the platform language.
|
||||
$valid_languages = api_get_languages();
|
||||
|
||||
if (!empty($valid_languages)) {
|
||||
if (!in_array($user_language, $valid_languages['folder'])) {
|
||||
$user_language = api_get_setting('platformLanguage');
|
||||
}
|
||||
|
||||
$language_priority1 = api_get_setting('languagePriority1');
|
||||
$language_priority2 = api_get_setting('languagePriority2');
|
||||
$language_priority3 = api_get_setting('languagePriority3');
|
||||
$language_priority4 = api_get_setting('languagePriority4');
|
||||
|
||||
if (isset($_GET['language']) ||
|
||||
(isset($_POST['language_list']) && !empty($_POST['language_list'])) ||
|
||||
!empty($browser_language)
|
||||
) {
|
||||
$user_selected_language = $user_language; // $_GET['language']; or HTTP_ACCEPT_LANGUAGE
|
||||
$_SESSION['user_language_choice'] = $user_selected_language;
|
||||
$platformLanguage = $user_selected_language;
|
||||
}
|
||||
|
||||
if (!empty($language_priority4) && api_get_language_from_type($language_priority4) !== false) {
|
||||
$language_interface = api_get_language_from_type($language_priority4);
|
||||
} else {
|
||||
$language_interface = api_get_setting('platformLanguage');
|
||||
}
|
||||
|
||||
if (!empty($language_priority3) && api_get_language_from_type($language_priority3) !== false) {
|
||||
$language_interface = api_get_language_from_type($language_priority3);
|
||||
} else {
|
||||
if (isset($_SESSION['user_language_choice'])) {
|
||||
$language_interface = $_SESSION['user_language_choice'];
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($language_priority2) && api_get_language_from_type($language_priority2) !== false) {
|
||||
$language_interface = api_get_language_from_type($language_priority2);
|
||||
} else {
|
||||
if (isset($_user['language'])) {
|
||||
$language_interface = $_user['language'];
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($language_priority1) && api_get_language_from_type($language_priority1) !== false) {
|
||||
$language_interface = api_get_language_from_type($language_priority1);
|
||||
} else {
|
||||
if (isset($_course['language'])) {
|
||||
$language_interface = $_course['language'];
|
||||
}
|
||||
}
|
||||
|
||||
// If language is set via browser ignore the priority
|
||||
if (isset($_GET['language'])) {
|
||||
$language_interface = $user_language;
|
||||
}
|
||||
|
||||
// Load the user language, if user is entering in the terms and condition page
|
||||
if (isset($_SESSION['term_and_condition']) && isset($_SESSION['term_and_condition']['user_id'])) {
|
||||
$userTempId = $_SESSION['term_and_condition']['user_id'];
|
||||
$userTempInfo = api_get_user_info($userTempId);
|
||||
if (!empty($userTempInfo['language'])) {
|
||||
$language_interface = $userTempInfo['language'];
|
||||
}
|
||||
}
|
||||
|
||||
$allow = api_get_configuration_value('show_language_selector_in_menu');
|
||||
// Overwrite all lang configs and use the menu language
|
||||
if ($allow) {
|
||||
if (isset($_SESSION['user_language_choice'])) {
|
||||
$userEntity = api_get_user_entity(api_get_user_id());
|
||||
if ($userEntity) {
|
||||
if (isset($_GET['language'])) {
|
||||
$language_interface = $_SESSION['user_language_choice'];
|
||||
$userEntity->setLanguage($language_interface);
|
||||
Database::getManager()->merge($userEntity);
|
||||
Database::getManager()->flush();
|
||||
|
||||
// Update cache
|
||||
api_get_user_info(
|
||||
api_get_user_id(),
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true
|
||||
);
|
||||
if (isset($_SESSION['_user'])) {
|
||||
$_SESSION['_user']['language'] = $language_interface;
|
||||
}
|
||||
}
|
||||
$language_interface = $_SESSION['user_language_choice'] = $userEntity->getLanguage();
|
||||
}
|
||||
} else {
|
||||
$userInfo = api_get_user_info();
|
||||
if (!empty($userInfo['language'])) {
|
||||
$_SESSION['user_language_choice'] = $userInfo['language'];
|
||||
$language_interface = $userInfo['language'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sometimes the variable $language_interface is changed
|
||||
// temporarily for achieving translation in different language.
|
||||
// We need to save the genuine value of this variable and
|
||||
// to use it within the function get_lang(...).
|
||||
$language_interface_initial_value = $language_interface;
|
||||
|
||||
/**
|
||||
* Include the trad4all language file.
|
||||
*/
|
||||
$languageFilesToLoad = api_get_language_files_to_load($language_interface);
|
||||
|
||||
foreach ($languageFilesToLoad as $languageFile) {
|
||||
include $languageFile;
|
||||
}
|
||||
|
||||
// include the local (contextual) parameters of this course or section
|
||||
require $includePath.'/local.inc.php';
|
||||
|
||||
// The global variable $text_dir has been defined in the language file trad4all.inc.php.
|
||||
// For determining text direction correspondent to the current language
|
||||
// we use now information from the internationalization library.
|
||||
$text_dir = api_get_text_direction();
|
||||
|
||||
// ===== "who is logged in?" module section =====
|
||||
|
||||
// check and modify the date of user in the track.e.online table
|
||||
if (!$x = strpos($_SERVER['PHP_SELF'], 'whoisonline.php')) {
|
||||
if (!empty($_user['user_id'])) {
|
||||
preventMultipleLogin($_user['user_id']);
|
||||
LoginCheck($_user['user_id']);
|
||||
}
|
||||
}
|
||||
|
||||
// ===== end "who is logged in?" module section =====
|
||||
|
||||
// Update of the logout_date field in the table track_e_login
|
||||
// (needed for the calculation of the total connection time)
|
||||
if (!isset($_SESSION['login_as']) && isset($_user) && isset($_user["user_id"])) {
|
||||
// if $_SESSION['login_as'] is set, then the user is an admin logged as the user
|
||||
Tracking::updateUserLastLogin($_user["user_id"]);
|
||||
}
|
||||
|
||||
// Add language_measure_frequency to your main/inc/conf/configuration.php in
|
||||
// order to generate language variables frequency measurements (you can then
|
||||
// see them through main/cron/lang/langstats.php)
|
||||
// The langstat object will then be used in the get_lang() function.
|
||||
// This block can be removed to speed things up a bit as it should only ever
|
||||
// be used in development versions.
|
||||
if (isset($_configuration['language_measure_frequency']) &&
|
||||
$_configuration['language_measure_frequency'] == 1
|
||||
) {
|
||||
require_once api_get_path(SYS_CODE_PATH).'/cron/lang/langstats.class.php';
|
||||
$langstats = new langstats();
|
||||
}
|
||||
|
||||
//Default quota for the course documents folder
|
||||
$default_quota = api_get_setting('default_document_quotum');
|
||||
//Just in case the setting is not correctly set
|
||||
if (empty($default_quota)) {
|
||||
$default_quota = 100000000;
|
||||
}
|
||||
|
||||
define('DEFAULT_DOCUMENT_QUOTA', $default_quota);
|
||||
// Forcing PclZip library to use a custom temporary folder.
|
||||
define('PCLZIP_TEMPORARY_DIR', api_get_path(SYS_ARCHIVE_PATH));
|
||||
|
||||
// Create web/build/main.js
|
||||
$webBuildPath = api_get_path(SYS_PUBLIC_PATH).'build/';
|
||||
if (!is_dir($webBuildPath)) {
|
||||
if (!mkdir($webBuildPath, api_get_permissions_for_new_directories())) {
|
||||
error_log(
|
||||
'Error: '.$webBuildPath.' could not be written. Please check permissions.'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Load template layout/main.js.tpl and save it into web/build/main.js
|
||||
$file = $webBuildPath.'main.js';
|
||||
if (!empty($language_interface)) {
|
||||
$file = $webBuildPath.'main.'.$language_interface.'.js';
|
||||
}
|
||||
|
||||
// if portal is in test mode always generate the file
|
||||
if (!file_exists($file) || api_get_setting('server_type') === 'test') {
|
||||
$template = new Template();
|
||||
$template->assign('quiz_markers_rolls_js', ChamiloApi::getQuizMarkersRollsJS());
|
||||
$template->assign('is_vrview_enabled', Display::isVrViewEnabled());
|
||||
// Force use of default to avoid problems
|
||||
$tpl = 'default/layout/main.js.tpl';
|
||||
$contents = $template->fetch($tpl);
|
||||
if (is_writable($webBuildPath)) {
|
||||
file_put_contents($file, $contents);
|
||||
} else {
|
||||
error_log(
|
||||
'Error: '.$file.' could not be written. Please check permissions. The web server must be able to write there.'
|
||||
);
|
||||
}
|
||||
}
|
||||
324
main/inc/global_error_message.inc.php
Normal file
324
main/inc/global_error_message.inc.php
Normal file
@@ -0,0 +1,324 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* This script displays error messages on fatal errors during initialization.
|
||||
*
|
||||
* @package chamilo.include
|
||||
*
|
||||
* @author Ivan Tcholakov, 2009-2010
|
||||
*/
|
||||
$Organisation = '<a href="http://www.chamilo.org" target="_blank">Chamilo Homepage</a>';
|
||||
$PoweredBy = 'Powered by <a href="http://www.chamilo.org" target="_blank"> Chamilo </a> © '.date('Y');
|
||||
|
||||
/**
|
||||
* English language variables.
|
||||
*/
|
||||
|
||||
// Sections.
|
||||
$SectionSystemRequirementsProblem = 'System requirements problem';
|
||||
$SectionInstallation = 'Installation';
|
||||
$SectionDatabaseUnavailable = 'Database is unavailable';
|
||||
$SectionTechnicalIssues = 'Technical issues';
|
||||
$SectionProtection = 'Protection measure';
|
||||
|
||||
// Error code.
|
||||
$ErrorCode = 'Error code';
|
||||
|
||||
// Error code 1.
|
||||
$IncorrectPhpVersionTitle = 'Incorrect PHP version';
|
||||
$IncorrectPhpVersionDescription = 'Warning: we have detected that your version of PHP is %s1. To install Chamilo, you need to have PHP %s2 or superior. If you don\'t know what we\'re talking about, please contact your hosting provider or your support team.
|
||||
%s3 Read the installation guide.';
|
||||
|
||||
// Error code 2.
|
||||
$InstallationTitle = 'Chamilo has not been installed';
|
||||
$InstallationDescription = 'Click to INSTALL Chamilo %s or read the installation guide';
|
||||
|
||||
// Error code 3.
|
||||
// Error code 4.
|
||||
// Error code 5.
|
||||
$DatabaseUnavailableTitle = 'Database is unavailable';
|
||||
$DatabaseUnavailableDescription = 'This portal is currently experiencing database issues. Please report this to the portal administrator. Thank you for your help.';
|
||||
|
||||
// Error code 6.
|
||||
$AlreadyInstalledTitle = 'Chamilo has already been installed';
|
||||
$AlreadyInstalledDescription = 'The system has already been installed. In order to protect its contents, we have to prevent you from starting the installation script again. Please return to the main page.';
|
||||
|
||||
// Unspecified error.
|
||||
$TechnicalIssuesTitle = 'Technical issues';
|
||||
$TechnicalIssuesDescription = 'This portal is currently experiencing technical issues. Please report this to the portal administrator. Thank you for your help.';
|
||||
|
||||
if (is_int($global_error_code) && $global_error_code > 0) {
|
||||
if (class_exists('Template') && function_exists('api_get_configuration_value')) {
|
||||
$theme = Template::getThemeFallback().'/';
|
||||
} else {
|
||||
$theme = 'chamilo';
|
||||
}
|
||||
|
||||
$root_rel = '';
|
||||
$installation_guide_url = $root_rel.'documentation/installation_guide.html';
|
||||
|
||||
$css_path = 'app/Resources/public/css/';
|
||||
$css_web_assets = 'web/assets/';
|
||||
$css_web_path = 'web/css/';
|
||||
$themePath = $css_path.'themes/'.$theme.'/default.css';
|
||||
$bootstrap_file = $css_web_assets.'bootstrap/dist/css/bootstrap.min.css';
|
||||
$css_base_file = $css_web_path.'base.css';
|
||||
|
||||
$css_list = [$bootstrap_file, $css_base_file, $themePath];
|
||||
|
||||
$web_img = 'main/img';
|
||||
$root_sys = str_replace('\\', '/', realpath(__DIR__.'/../../')).'/';
|
||||
|
||||
$css_def = '';
|
||||
foreach ($css_list as $cssFile) {
|
||||
$cssFile = $root_sys.$cssFile;
|
||||
if (file_exists($cssFile)) {
|
||||
$css_def .= file_get_contents($cssFile);
|
||||
}
|
||||
}
|
||||
|
||||
$css_def = str_replace("themes/$theme/", $css_web_path."themes/$theme/", $css_def);
|
||||
|
||||
$global_error_message = [];
|
||||
|
||||
switch ($global_error_code) {
|
||||
case 1:
|
||||
$global_error_message['section'] = $SectionSystemRequirementsProblem;
|
||||
$global_error_message['title'] = $IncorrectPhpVersionTitle;
|
||||
$php_version = function_exists('phpversion') ? phpversion() : (defined('PHP_VERSION') ? PHP_VERSION : '');
|
||||
$php_version = empty($php_version) ? '' : '(PHP '.$php_version.')';
|
||||
$IncorrectPhpVersionDescription = str_replace('%s1', $php_version, $IncorrectPhpVersionDescription);
|
||||
$IncorrectPhpVersionDescription = str_replace('%s2', REQUIRED_PHP_VERSION, $IncorrectPhpVersionDescription);
|
||||
$pos = strpos($IncorrectPhpVersionDescription, '%s3');
|
||||
if ($pos !== false) {
|
||||
$length = strlen($IncorrectPhpVersionDescription);
|
||||
$read_installation_guide = substr($IncorrectPhpVersionDescription, $pos + 3, $length);
|
||||
$IncorrectPhpVersionDescription = substr($IncorrectPhpVersionDescription, 0, $pos);
|
||||
$IncorrectPhpVersionDescription .= '<br /><a class="btn btn-default" href="'.$installation_guide_url.'" target="_blank">'.$read_installation_guide.'</a>';
|
||||
}
|
||||
$global_error_message['description'] = $IncorrectPhpVersionDescription;
|
||||
break;
|
||||
case 2:
|
||||
require __DIR__.'/../install/version.php';
|
||||
$global_error_message['section'] = $SectionInstallation;
|
||||
$global_error_message['title'] = $InstallationTitle;
|
||||
if (($pos = strpos($InstallationDescription, '%s')) === false) {
|
||||
$InstallationDescription = 'Click to INSTALL Chamilo %s or read the installation guide';
|
||||
}
|
||||
$read_installation_guide = substr($InstallationDescription, $pos + 2);
|
||||
$versionStatus = (!empty($new_version_status) && $new_version_status != 'stable' ? $new_version_status : '');
|
||||
$InstallationDescription = '<form action="'.$root_rel.'main/install/index.php" method="get">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="office">
|
||||
<h2 class="title">Welcome to the Chamilo '.$new_version.' '.$new_version_status.' installation wizard</h2>
|
||||
<p class="text">Let\'s start hunting skills down with Chamilo LMS! This wizard will guide you through the Chamilo installation and configuration process.</p>
|
||||
<p class="download-info">
|
||||
<button class="btn btn-primary btn-lg" type="submit" value="INSTALL Chamilo" ><i class="fa fa-download" aria-hidden="true"></i> Install Chamilo</button>
|
||||
<a class="btn btn-success btn-lg" href="'.$installation_guide_url.'" target="_blank"> '.$read_installation_guide.'</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>';
|
||||
$global_error_message['description'] = $InstallationDescription;
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
$global_error_message['section'] = $SectionDatabaseUnavailable;
|
||||
$global_error_message['title'] = $DatabaseUnavailableTitle;
|
||||
$global_error_message['description'] = $DatabaseUnavailableDescription;
|
||||
break;
|
||||
case 6:
|
||||
$global_error_message['section'] = $SectionProtection;
|
||||
$global_error_message['title'] = $AlreadyInstalledTitle;
|
||||
$global_error_message['description'] = $AlreadyInstalledDescription;
|
||||
break;
|
||||
default:
|
||||
$global_error_message['section'] = $SectionTechnicalIssues;
|
||||
$global_error_message['title'] = $TechnicalIssuesTitle;
|
||||
$global_error_message['description'] = $TechnicalIssuesDescription;
|
||||
break;
|
||||
}
|
||||
|
||||
$show_error_codes = defined('SHOW_ERROR_CODES') && SHOW_ERROR_CODES && $global_error_code != 2;
|
||||
$global_error_message['code'] = $show_error_codes ? $ErrorCode.': '.$global_error_code.'<br /><br />' : '';
|
||||
$global_error_message['details'] = empty($global_error_message['details']) ? '' : ($show_error_codes ? ': '.$global_error_message['details'] : $global_error_message['details']);
|
||||
$global_error_message['organisation'] = $Organisation;
|
||||
$global_error_message['powered_by'] = $PoweredBy;
|
||||
$global_error_message['encoding'] = 'UTF-8';
|
||||
$global_error_message['chamilo_logo'] = "data:image/png;base64,".base64_encode(file_get_contents($root_sys.'web/css/themes/'.$theme.'/images/header-logo.png'));
|
||||
$bgImage = base64_encode(file_get_contents("$root_sys/main/img/bg_space.png"));
|
||||
$bgMoon = base64_encode(file_get_contents("$root_sys/main/img/bg_moon_two.png"));
|
||||
$installChamiloImage = "data:image/png;base64,".base64_encode(file_get_contents("$root_sys/main/img/mr_chamilo_install.png"));
|
||||
$global_error_message['mr_chamilo'] = $installChamiloImage;
|
||||
|
||||
if ($global_error_code == 2) {
|
||||
$global_error_message_page =
|
||||
<<<EOM
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>{TITLE}</title>
|
||||
<meta charset="{ENCODING}" />
|
||||
|
||||
<style>
|
||||
$css_def
|
||||
html, body {min-height:100%; padding:0; margin:0;}
|
||||
|
||||
#wrapper {padding:0; position:absolute; top:0; bottom:0; left:0; right:0;}
|
||||
@keyframes animatedBackground {
|
||||
from { background-position: 0 0; }
|
||||
to { background-position: 100% 0; }
|
||||
}
|
||||
@-webkit-keyframes animatedBackground {
|
||||
from { background-position: 0 0; }
|
||||
to { background-position: 100% 0; }
|
||||
}
|
||||
@-ms-keyframes animatedBackground {
|
||||
from { background-position: 0 0; }
|
||||
to { background-position: 100% 0; }
|
||||
}
|
||||
@-moz-keyframes animatedBackground {
|
||||
from { background-position: 0 0; }
|
||||
to { background-position: 100% 0; }
|
||||
}
|
||||
.install-home{
|
||||
background-image: url("data:image/png;base64,$bgImage");
|
||||
background-position: 0px 0px;
|
||||
background-repeat: repeat;
|
||||
animation: animatedBackground 40s linear infinite;
|
||||
-ms-animation: animatedBackground 40s linear infinite;
|
||||
-moz-animation: animatedBackground 40s linear infinite;
|
||||
-webkit-animation: animatedBackground 40s linear infinite;
|
||||
}
|
||||
.installer{
|
||||
background: url("data:image/png;base64,$bgMoon") no-repeat center 390px;
|
||||
}
|
||||
.avatar{
|
||||
text-align: center;
|
||||
}
|
||||
.avatar .img-responsive{
|
||||
display: initial;
|
||||
}
|
||||
.office{
|
||||
padding: 10px 20px;
|
||||
//background-color: rgba(35, 40, 56, 0.7);
|
||||
background-color: rgba(0, 22, 48, 0.8);
|
||||
border-radius: 5px;
|
||||
}
|
||||
@media (max-width: 480px) {
|
||||
.download-info .btn-success{
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="install-home">
|
||||
<div id="wrapper" class="installer">
|
||||
<header>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="logo">
|
||||
<img src="{CHAMILO_LOGO}"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div id="content">
|
||||
<div class="container">
|
||||
<div class="welcome-install">
|
||||
<div class="avatar">
|
||||
<img class="img-responsive" src="{MR_CHAMILO}"/>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="office">
|
||||
<p class="text">
|
||||
{DESCRIPTION}
|
||||
{CODE}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
EOM;
|
||||
} else {
|
||||
$global_error_message_page =
|
||||
<<<EOM
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>{TITLE}</title>
|
||||
<meta charset="{ENCODING}" />
|
||||
<style>
|
||||
$css_def
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="page-error">
|
||||
<div class="page-wrap">
|
||||
<header>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="logo">
|
||||
<img src="{CHAMILO_LOGO}"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<section id="menu-bar">
|
||||
<nav class="navbar navbar-default">
|
||||
<div class="container">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#menuone" aria-expanded="false">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="collapse navbar-collapse" id="menuone">
|
||||
<ul class="nav navbar-nav">
|
||||
<li id="current" class="active tab-homepage"><a href="#" target="_self">Homepage</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</section>
|
||||
|
||||
<section id="content-error">
|
||||
<div class="container">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
<div class="alert alert-danger" role="alert">
|
||||
{DESCRIPTION}
|
||||
{CODE}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
EOM;
|
||||
}
|
||||
foreach ($global_error_message as $key => $value) {
|
||||
$global_error_message_page = str_replace('{'.strtoupper($key).'}', $value, $global_error_message_page);
|
||||
}
|
||||
header('Content-Type: text/html; charset='.$global_error_message['encoding']);
|
||||
exit($global_error_message_page);
|
||||
}
|
||||
6
main/inc/index.html
Normal file
6
main/inc/index.html
Normal file
@@ -0,0 +1,6 @@
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
423
main/inc/introductionSection.inc.php
Normal file
423
main/inc/introductionSection.inc.php
Normal file
@@ -0,0 +1,423 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use Chamilo\CoreBundle\Entity\SequenceResource;
|
||||
use Chamilo\CourseBundle\Entity\CToolIntro;
|
||||
|
||||
/**
|
||||
* The INTRODUCTION MICRO MODULE is used to insert and edit
|
||||
* an introduction section on a Chamilo module or on the course homepage.
|
||||
* It can be inserted on any Chamilo module, provided the corresponding setting
|
||||
* is enabled in the administration section.
|
||||
*
|
||||
* The introduction content are stored in a table called "tool_intro"
|
||||
* in the course Database. Each module introduction has an Id stored in
|
||||
* the table, which matches a specific module.
|
||||
*
|
||||
* '(c_)tool_intro' table description
|
||||
* c_id: int
|
||||
* id : int
|
||||
* intro_text :text
|
||||
* session_id: int
|
||||
*
|
||||
* usage :
|
||||
*
|
||||
* $moduleId = 'XX'; // specifying the module tool (string value)
|
||||
* include(introductionSection.inc.php);
|
||||
*
|
||||
* This script is also used since Chamilo 1.9 to show course progress (from the
|
||||
* course_progress module)
|
||||
*/
|
||||
$em = Database::getManager();
|
||||
$intro_editAllowed = $is_allowed_to_edit = api_is_allowed_to_edit();
|
||||
$session_id = api_get_session_id();
|
||||
$blogParam = isset($_GET['blog_id']) ? ('&blog_id='.(int) $_GET['blog_id']) : '';
|
||||
$cidReq = api_get_cidreq();
|
||||
|
||||
$introduction_section = '';
|
||||
|
||||
global $charset;
|
||||
$intro_cmdEdit = empty($_GET['intro_cmdEdit']) ? '' : $_GET['intro_cmdEdit'];
|
||||
$intro_cmdUpdate = isset($_POST['intro_cmdUpdate']);
|
||||
$intro_cmdDel = empty($_GET['intro_cmdDel']) ? '' : $_GET['intro_cmdDel'];
|
||||
$intro_cmdAdd = empty($_GET['intro_cmdAdd']) ? '' : $_GET['intro_cmdAdd'];
|
||||
$courseId = api_get_course_id();
|
||||
|
||||
if (!empty($courseId)) {
|
||||
$form = new FormValidator(
|
||||
'introduction_text',
|
||||
'post',
|
||||
api_get_self().'?'.$cidReq.$blogParam
|
||||
);
|
||||
} else {
|
||||
$form = new FormValidator('introduction_text');
|
||||
}
|
||||
|
||||
$config = [
|
||||
'ToolbarSet' => 'IntroductionSection',
|
||||
'Width' => '100%',
|
||||
'Height' => '300',
|
||||
];
|
||||
|
||||
$form->addHtmlEditor('intro_content', null, false, false, $config);
|
||||
$form->addButtonSave(get_lang('SaveIntroText'), 'intro_cmdUpdate');
|
||||
|
||||
/* INTRODUCTION MICRO MODULE - COMMANDS SECTION (IF ALLOWED) */
|
||||
$course_id = api_get_course_int_id();
|
||||
|
||||
if ($intro_editAllowed) {
|
||||
/** @var CToolIntro $toolIntro */
|
||||
$toolIntro = $em
|
||||
->getRepository('ChamiloCourseBundle:CToolIntro')
|
||||
->findOneBy(['cId' => $course_id, 'id' => $moduleId, 'sessionId' => $session_id]);
|
||||
|
||||
/* Replace command */
|
||||
if ($intro_cmdUpdate) {
|
||||
if ($form->validate()) {
|
||||
$form_values = $form->exportValues();
|
||||
$intro_content = $form_values['intro_content'];
|
||||
if (!empty($intro_content)) {
|
||||
if (!$toolIntro) {
|
||||
$toolIntro = new CToolIntro();
|
||||
$toolIntro
|
||||
->setSessionId($session_id)
|
||||
->setCId($course_id)
|
||||
->setId($moduleId);
|
||||
}
|
||||
|
||||
$toolIntro->setIntroText($intro_content);
|
||||
|
||||
$em->persist($toolIntro);
|
||||
$em->flush();
|
||||
Display::addFlash(Display::return_message(get_lang('IntroductionTextUpdated'), 'confirmation', false));
|
||||
} else {
|
||||
// got to the delete command
|
||||
$intro_cmdDel = true;
|
||||
}
|
||||
} else {
|
||||
$intro_cmdEdit = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Delete Command */
|
||||
if ($intro_cmdDel && $toolIntro) {
|
||||
$em->remove($toolIntro);
|
||||
$em->flush();
|
||||
|
||||
Display::addFlash(Display::return_message(get_lang('IntroductionTextDeleted'), 'confirmation'));
|
||||
}
|
||||
}
|
||||
|
||||
/* INTRODUCTION MICRO MODULE - DISPLAY SECTION */
|
||||
|
||||
/* Retrieves the module introduction text, if exist */
|
||||
// Getting course intro
|
||||
/** @var CToolIntro $toolIntro */
|
||||
$toolIntro = $em
|
||||
->getRepository('ChamiloCourseBundle:CToolIntro')
|
||||
->findOneBy(['cId' => $course_id, 'id' => $moduleId, 'sessionId' => 0]);
|
||||
|
||||
$intro_content = $toolIntro ? $toolIntro->getIntroText() : '';
|
||||
if ($session_id) {
|
||||
/** @var CToolIntro $toolIntro */
|
||||
$toolIntro = $em
|
||||
->getRepository('ChamiloCourseBundle:CToolIntro')
|
||||
->findOneBy(['cId' => $course_id, 'id' => $moduleId, 'sessionId' => $session_id]);
|
||||
|
||||
$introSessionContent = $toolIntro && $toolIntro->getIntroText() ? $toolIntro->getIntroText() : '';
|
||||
$intro_content = $introSessionContent ?: $intro_content;
|
||||
}
|
||||
|
||||
// Default behaviour show iframes.
|
||||
$userStatus = COURSEMANAGERLOWSECURITY;
|
||||
|
||||
// Allows to do a remove_XSS in course introduction with user status COURSEMANAGERLOWSECURITY
|
||||
// Block embed type videos (like vimeo, wistia, etc) - see BT#12244 BT#12556
|
||||
if (api_get_configuration_value('course_introduction_html_strict_filtering')) {
|
||||
$userStatus = COURSEMANAGER;
|
||||
}
|
||||
|
||||
// Ignore editor.css
|
||||
$cssEditor = api_get_path(WEB_CSS_PATH).'editor.css';
|
||||
$linkToReplace = [
|
||||
'<link href="'.$cssEditor.'" rel="stylesheet" type="text/css" />',
|
||||
'<link href="'.$cssEditor.'" media="screen" rel="stylesheet" type="text/css" />',
|
||||
];
|
||||
$intro_content = str_replace($linkToReplace, '', $intro_content);
|
||||
$intro_content = Security::remove_XSS($intro_content, $userStatus);
|
||||
|
||||
/* Determines the correct display */
|
||||
if ($intro_cmdEdit || $intro_cmdAdd) {
|
||||
$intro_dispDefault = false;
|
||||
$intro_dispForm = true;
|
||||
$intro_dispCommand = false;
|
||||
} else {
|
||||
$intro_dispDefault = true;
|
||||
$intro_dispForm = false;
|
||||
|
||||
if ($intro_editAllowed) {
|
||||
$intro_dispCommand = true;
|
||||
} else {
|
||||
$intro_dispCommand = false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Executes the display */
|
||||
|
||||
// display thematic advance inside a postit
|
||||
if ($intro_dispForm) {
|
||||
$default['intro_content'] = $intro_content;
|
||||
$form->setDefaults($default);
|
||||
$introduction_section .= '<div id="courseintro" style="width: 98%">';
|
||||
$introduction_section .= $form->returnForm();
|
||||
$introduction_section .= '</div>';
|
||||
}
|
||||
|
||||
$thematic_description_html = '';
|
||||
$thematicItemTwo = '';
|
||||
|
||||
if ($tool == TOOL_COURSE_HOMEPAGE && !isset($_GET['intro_cmdEdit'])) {
|
||||
// Only show this if we're on the course homepage, and we're not currently editing
|
||||
$thematic = new Thematic();
|
||||
$displayMode = api_get_course_setting('display_info_advance_inside_homecourse');
|
||||
$class1 = '';
|
||||
if ($displayMode == '1') {
|
||||
// Show only the current course progress step
|
||||
$last_done_advance = $thematic->get_last_done_thematic_advance();
|
||||
$thematic_advance_info = $thematic->get_thematic_advance_list($last_done_advance);
|
||||
$subTitle1 = get_lang('CurrentTopic');
|
||||
$class1 = ' current';
|
||||
} elseif ($displayMode == '2') {
|
||||
// Show only the two next course progress steps
|
||||
$last_done_advance = $thematic->get_next_thematic_advance_not_done();
|
||||
$next_advance_not_done = $thematic->get_next_thematic_advance_not_done(2);
|
||||
$thematic_advance_info = $thematic->get_thematic_advance_list($last_done_advance);
|
||||
$thematic_advance_info2 = $thematic->get_thematic_advance_list($next_advance_not_done);
|
||||
$subTitle1 = $subTitle2 = get_lang('NextTopic');
|
||||
} elseif ($displayMode == '3') {
|
||||
// Show the current and next course progress steps
|
||||
$last_done_advance = $thematic->get_last_done_thematic_advance();
|
||||
$next_advance_not_done = $thematic->get_next_thematic_advance_not_done();
|
||||
$thematic_advance_info = $thematic->get_thematic_advance_list($last_done_advance);
|
||||
$thematic_advance_info2 = $thematic->get_thematic_advance_list($next_advance_not_done);
|
||||
$subTitle1 = get_lang('CurrentTopic');
|
||||
$subTitle2 = get_lang('NextTopic');
|
||||
$class1 = ' current';
|
||||
}
|
||||
|
||||
if (!empty($thematic_advance_info)) {
|
||||
$thematic_advance = get_lang('CourseThematicAdvance');
|
||||
$thematicScore = $thematic->get_total_average_of_thematic_advances().'%';
|
||||
$thematicUrl = api_get_path(WEB_CODE_PATH).'course_progress/index.php?action=thematic_details&'.$cidReq;
|
||||
|
||||
$thematic_advance_info['thematic_id'] = $thematic_advance_info['thematic_id'] ?? 0;
|
||||
$thematic_advance_info['start_date'] = $thematic_advance_info['start_date'] ?? null;
|
||||
$thematic_advance_info['content'] = $thematic_advance_info['content'] ?? '';
|
||||
$thematic_advance_info['duration'] = $thematic_advance_info['duration'] ?? 0;
|
||||
|
||||
$thematic_info = $thematic->get_thematic_list($thematic_advance_info['thematic_id']);
|
||||
$thematic_info['title'] = $thematic_info['title'] ?? '';
|
||||
|
||||
if (!empty($thematic_advance_info['start_date'])) {
|
||||
$thematic_advance_info['start_date'] = api_get_local_time(
|
||||
$thematic_advance_info['start_date']
|
||||
);
|
||||
}
|
||||
|
||||
$thematic_advance_info['start_date'] = api_format_date(
|
||||
$thematic_advance_info['start_date'],
|
||||
DATE_TIME_FORMAT_LONG
|
||||
);
|
||||
$userInfo = api_get_user_info();
|
||||
$courseInfo = api_get_course_info();
|
||||
$titleThematic = $thematic_advance.' : '.$courseInfo['name'].' <b>( '.$thematicScore.' )</b>';
|
||||
|
||||
$infoUser = '<div class="thematic-avatar"><img src="'.$userInfo['avatar'].'" class="img-circle img-responsive"></div>';
|
||||
$infoUser .= '<div class="progress">
|
||||
<div class="progress-bar progress-bar-primary" role="progressbar" style="width: '.$thematicScore.';">
|
||||
'.$thematicScore.'
|
||||
</div>
|
||||
</div>';
|
||||
|
||||
$thematicItemOne = '
|
||||
<div class="col-md-6 items-progress">
|
||||
<div class="thematic-cont '.$class1.'">
|
||||
<div class="topics">'.$subTitle1.'</div>
|
||||
<h4 class="title-topics">'.Display::returnFontAwesomeIcon('book').strip_tags($thematic_info['title']).'</h4>
|
||||
<p class="date">'.Display::returnFontAwesomeIcon('calendar-o').$thematic_advance_info['start_date'].'</p>
|
||||
<div class="views">'.Display::returnFontAwesomeIcon('file-text-o').strip_tags($thematic_advance_info['content']).'</div>
|
||||
<p class="time">'.Display::returnFontAwesomeIcon('clock-o').get_lang('DurationInHours').' : '.$thematic_advance_info['duration'].' - <a href="'.$thematicUrl.'">'.get_lang('SeeDetail').'</a></p>
|
||||
</div>
|
||||
</div>';
|
||||
|
||||
if (!empty($thematic_advance_info2)) {
|
||||
$thematic_info2 = $thematic->get_thematic_list($thematic_advance_info2['thematic_id']);
|
||||
$thematic_advance_info2['start_date'] = api_get_local_time($thematic_advance_info2['start_date']);
|
||||
$thematic_advance_info2['start_date'] = api_format_date($thematic_advance_info2['start_date'], DATE_TIME_FORMAT_LONG);
|
||||
|
||||
$thematicItemTwo = '
|
||||
<div class="col-md-6 items-progress">
|
||||
<div class="thematic-cont">
|
||||
<div class="topics">'.$subTitle2.'</div>
|
||||
<h4 class="title-topics">'.Display::returnFontAwesomeIcon('book').$thematic_info2['title'].'</h4>
|
||||
<p class="date">'.Display::returnFontAwesomeIcon('calendar-o').$thematic_advance_info2['start_date'].'</p>
|
||||
<div class="views">'.Display::returnFontAwesomeIcon('file-text-o').strip_tags($thematic_advance_info2['content']).'</div>
|
||||
<p class="time">'.Display::returnFontAwesomeIcon('clock-o').get_lang('DurationInHours').' : '.$thematic_advance_info2['duration'].' - <a href="'.$thematicUrl.'">'.get_lang('SeeDetail').'</a></p>
|
||||
</div>
|
||||
</div>';
|
||||
}
|
||||
$thematicPanel = '<div class="row">';
|
||||
$thematicPanel .= '<div class="col-md-2">'.$infoUser.'</div>';
|
||||
$thematicPanel .= '<div class="col-md-10"><div class="row">'.$thematicItemOne.$thematicItemTwo.'</div></div>';
|
||||
$thematicPanel .= '</div>';
|
||||
$thematicPanel .= '<div class="separate">
|
||||
<a href="'.$thematicUrl.'" class="btn btn-default btn-block">'.get_lang('ShowFullCourseAdvance').'</a>
|
||||
</div>';
|
||||
|
||||
$thematicProgress = Display::panelCollapse(
|
||||
$titleThematic,
|
||||
$thematicPanel,
|
||||
'thematic',
|
||||
null,
|
||||
'accordion-thematic',
|
||||
'collapse-thematic',
|
||||
false
|
||||
);
|
||||
}
|
||||
}
|
||||
$introduction_section .= '<div class="row">';
|
||||
if (!empty($thematic_advance_info)) {
|
||||
$introduction_section .= '<div class="col-md-12">';
|
||||
$introduction_section .= $thematic_description_html;
|
||||
$introduction_section .= $thematicProgress;
|
||||
$introduction_section .= '</div>';
|
||||
}
|
||||
$editIconButton = '';
|
||||
if (api_is_allowed_to_edit() && empty($session_id)) {
|
||||
$editIconButton = Display::url(
|
||||
'<em class="fa fa-wrench"></em> ',
|
||||
api_get_path(WEB_CODE_PATH).'course_info/tools.php?'.$cidReq,
|
||||
['class' => 'btn btn-default', 'title' => get_lang('CustomizeIcons')]
|
||||
);
|
||||
}
|
||||
/* Tool to show /hide all tools on course */
|
||||
$toolAllShowHide = '';
|
||||
if (api_is_allowed_to_edit() && empty($session_id)) {
|
||||
$toolAllShowHide = '<button class="btn btn-default hidden visible-all show-hide-all-tools" title="'.get_lang('Activate', '').'"><em class="fa fa-eye"></em></button>';
|
||||
$toolAllShowHide .= '<button class="btn btn-default hidden invisible-all show-hide-all-tools" title="'.get_lang('Deactivate', '').'"><em class="fa fa-eye-slash"></em></button>';
|
||||
}
|
||||
|
||||
$toolbar = '';
|
||||
$textIntro = '';
|
||||
if ($intro_dispCommand) {
|
||||
$toolbar .= '<div class="toolbar-edit">';
|
||||
$toolbar .= '<div class="btn-group pull-right" role="group">';
|
||||
if (empty($intro_content)) {
|
||||
// Displays "Add intro" commands
|
||||
if (!empty($courseId)) {
|
||||
$textIntro = '<a class="btn btn-default" title="'.addslashes(get_lang('AddIntro')).'" href="'.api_get_self().'?'.$cidReq.$blogParam.'&intro_cmdAdd=1">';
|
||||
$textIntro .= '<em class="fa fa-file-text"></em> ';
|
||||
$textIntro .= "</a>";
|
||||
$toolbar .= $textIntro.$editIconButton.$toolAllShowHide;
|
||||
} else {
|
||||
$toolbar .= '<a class="btn btn-default" href="'.api_get_self().'?intro_cmdAdd=1">'.get_lang('AddIntro').'</a>';
|
||||
$toolbar .= $editIconButton.$toolAllShowHide;
|
||||
}
|
||||
} else {
|
||||
// Displays "edit intro && delete intro" commands
|
||||
if (!empty($courseId)) {
|
||||
$toolbar .=
|
||||
'<a class="btn btn-default" href="'.api_get_self().'?'.$cidReq.$blogParam.'&intro_cmdEdit=1" title="'.get_lang('Modify').'">
|
||||
<em class="fa fa-pencil"></em></a>';
|
||||
$toolbar .= $editIconButton.$toolAllShowHide;
|
||||
$toolbar .= "<a class=\"btn btn-default\"
|
||||
href=\"".api_get_self()."?".$cidReq.$blogParam."&intro_cmdDel=1\"
|
||||
onclick=\"if(!confirm('".addslashes(api_htmlentities(get_lang('ConfirmYourChoice'), ENT_QUOTES, $charset))."')) return false;\"
|
||||
><em class=\"fa fa-trash-o\"></em></a>";
|
||||
} else {
|
||||
$toolbar .=
|
||||
'<a class="btn btn-default" href="'.api_get_self().'?intro_cmdEdit=1" title="'.get_lang('Modify').'">
|
||||
<em class="fa fa-pencil"></em>
|
||||
</a>"';
|
||||
$toolbar .= $editIconButton.$toolAllShowHide;
|
||||
$toolbar .= "<a class=\"btn btn-default\"
|
||||
href=\"".api_get_self()."?".$cidReq."&intro_cmdDel=1\"
|
||||
onclick=\"if(!confirm('".addslashes(api_htmlentities(get_lang('ConfirmYourChoice'), ENT_QUOTES, $charset))."')) return false;\"
|
||||
><em class=\"fa fa-trash-o\"></em></a>";
|
||||
}
|
||||
// Fix for chrome XSS filter for videos in iframes - BT#7930
|
||||
$browser = api_get_navigator();
|
||||
if (strpos($introduction_section, '<iframe') !== false && $browser['name'] == 'Chrome') {
|
||||
header('X-XSS-Protection: 0');
|
||||
}
|
||||
}
|
||||
$toolbar .= '</div></div>';
|
||||
}
|
||||
|
||||
$nameSection = get_lang('AddCustomCourseIntro');
|
||||
if ($moduleId !== 'course_homepage') {
|
||||
$nameSection = get_lang('AddCustomToolsIntro');
|
||||
}
|
||||
|
||||
if (!api_is_anonymous()) {
|
||||
$intro_content = AnnouncementManager::parseContent(api_get_user_id(), $intro_content, api_get_course_id());
|
||||
}
|
||||
|
||||
$showSequencesBlock = false;
|
||||
|
||||
if (api_get_configuration_value('resource_sequence_show_dependency_in_course_intro' && $tool == TOOL_COURSE_HOMEPAGE)) {
|
||||
$sequenceResourceRepo = $em->getRepository(SequenceResource::class);
|
||||
$sequences = $sequenceResourceRepo->getDependents($course_id, SequenceResource::COURSE_TYPE);
|
||||
$firstSequence = current($sequences);
|
||||
|
||||
$showSequencesBlock = !empty($firstSequence['dependents']);
|
||||
}
|
||||
|
||||
$introduction_section .= $showSequencesBlock ? '<div class="col-md-10">' : '<div class="col-md-12">';
|
||||
|
||||
if ($intro_dispDefault) {
|
||||
if (!empty($intro_content)) {
|
||||
$introduction_section .= '<div class="page-course">';
|
||||
$introduction_section .= $intro_content;
|
||||
$introduction_section .= '</div>';
|
||||
} else {
|
||||
if (api_is_allowed_to_edit()) {
|
||||
$introduction_section .= '<div class="help-course">';
|
||||
$introduction_section .= $nameSection.' '.$textIntro;
|
||||
$introduction_section .= '</div>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$introduction_section .= $toolbar;
|
||||
$introduction_section .= '</div>';
|
||||
|
||||
if ($showSequencesBlock) {
|
||||
$sequenceUrl = http_build_query(
|
||||
[
|
||||
'a' => 'get_dependents',
|
||||
'id' => $course_id,
|
||||
'type' => SequenceResource::COURSE_TYPE,
|
||||
'sid' => $session_id,
|
||||
]
|
||||
);
|
||||
|
||||
$introduction_section .= '<div class="col-md-2 text-center" id="resource-sequence">
|
||||
<span class="fa fa-spinner fa-spin fa-fw" aria-hidden="true"></span>
|
||||
</div>
|
||||
<script>
|
||||
$(function () {
|
||||
$(\'#resource-sequence\').load(_p.web_ajax + \'sequence.ajax.php?'.$sequenceUrl.'&'.$cidReq.'\')
|
||||
});
|
||||
</script>
|
||||
';
|
||||
}
|
||||
|
||||
$introduction_section .= '</div>'; //div.row
|
||||
|
||||
$browser = api_get_navigator();
|
||||
|
||||
if (strpos($introduction_section, '<iframe') !== false && $browser['name'] == 'Chrome') {
|
||||
header("X-XSS-Protection: 0");
|
||||
}
|
||||
1
main/inc/lib/.htaccess
Normal file
1
main/inc/lib/.htaccess
Normal file
@@ -0,0 +1 @@
|
||||
Options -Indexes
|
||||
441
main/inc/lib/AnnouncementEmail.php
Normal file
441
main/inc/lib/AnnouncementEmail.php
Normal file
@@ -0,0 +1,441 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Announcement Email.
|
||||
*
|
||||
* @author Laurent Opprecht <laurent@opprecht.info> for the Univesity of Geneva
|
||||
* @author Julio Montoya <gugli100@gmail.com> Adding session support
|
||||
*/
|
||||
class AnnouncementEmail
|
||||
{
|
||||
public $session_id = null;
|
||||
public $logger;
|
||||
protected $course = null;
|
||||
protected $announcement = null;
|
||||
|
||||
/**
|
||||
* @param array $courseInfo
|
||||
* @param int $sessionId
|
||||
* @param int $announcementId
|
||||
* @param \Monolog\Logger $logger
|
||||
*/
|
||||
public function __construct($courseInfo, $sessionId, $announcementId, $logger = null)
|
||||
{
|
||||
if (empty($courseInfo)) {
|
||||
$courseInfo = api_get_course_info();
|
||||
}
|
||||
|
||||
$this->course = $courseInfo;
|
||||
$this->session_id = empty($sessionId) ? api_get_session_id() : (int) $sessionId;
|
||||
|
||||
if (is_numeric($announcementId)) {
|
||||
$this->announcement = AnnouncementManager::get_by_id($courseInfo['real_id'], $announcementId);
|
||||
}
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Course info.
|
||||
*
|
||||
* @param string $key
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function course($key = '')
|
||||
{
|
||||
$result = $key ? $this->course[$key] : $this->course;
|
||||
$result = $key == 'id' ? intval($result) : $result;
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Announcement info.
|
||||
*
|
||||
* @param string $key
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function announcement($key = '')
|
||||
{
|
||||
$result = $key ? $this->announcement[$key] : $this->announcement;
|
||||
$result = $key == 'id' ? intval($result) : $result;
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns either all course users or all session users depending on whether
|
||||
* session is turned on or not.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function all_users()
|
||||
{
|
||||
$courseCode = $this->course('code');
|
||||
if (empty($this->session_id)) {
|
||||
$group_id = api_get_group_id();
|
||||
if (empty($group_id)) {
|
||||
$userList = CourseManager::get_user_list_from_course_code($courseCode);
|
||||
} else {
|
||||
$userList = GroupManager::get_users($group_id);
|
||||
$new_user_list = [];
|
||||
foreach ($userList as $user) {
|
||||
$new_user_list[] = ['user_id' => $user];
|
||||
}
|
||||
$userList = $new_user_list;
|
||||
}
|
||||
} else {
|
||||
$userList = CourseManager::get_user_list_from_course_code(
|
||||
$courseCode,
|
||||
$this->session_id
|
||||
);
|
||||
}
|
||||
|
||||
return $userList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns users and groups an announcement item has been sent to.
|
||||
*
|
||||
* @return array Array of users and groups to whom the element has been sent
|
||||
*/
|
||||
public function sent_to_info()
|
||||
{
|
||||
$result = [];
|
||||
$result['groups'] = [];
|
||||
$result['users'] = [];
|
||||
|
||||
$table = Database::get_course_table(TABLE_ITEM_PROPERTY);
|
||||
$tool = TOOL_ANNOUNCEMENT;
|
||||
$id = $this->announcement('id');
|
||||
$course_id = $this->course('real_id');
|
||||
$sessionCondition = api_get_session_condition($this->session_id);
|
||||
|
||||
$sql = "SELECT to_group_id, to_user_id
|
||||
FROM $table
|
||||
WHERE
|
||||
c_id = $course_id AND
|
||||
tool = '$tool' AND
|
||||
ref = $id
|
||||
$sessionCondition";
|
||||
|
||||
$rs = Database::query($sql);
|
||||
|
||||
while ($row = Database::fetch_array($rs, 'ASSOC')) {
|
||||
// if to_user_id <> 0 then it is sent to a specific user
|
||||
$user_id = $row['to_user_id'];
|
||||
if (!empty($user_id)) {
|
||||
$result['users'][] = (int) $user_id;
|
||||
// If user is set then skip the group
|
||||
continue;
|
||||
}
|
||||
|
||||
// if to_group_id is null then it is sent to a specific user
|
||||
// if to_group_id = 0 then it is sent to everybody
|
||||
$group_id = $row['to_group_id'];
|
||||
if (!empty($group_id)) {
|
||||
$result['groups'][] = (int) $group_id;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of user info to which an announcement was sent.
|
||||
* This function returns a list of actual users even when recipient
|
||||
* are groups.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function sent_to()
|
||||
{
|
||||
$sent_to = $this->sent_to_info();
|
||||
$users = $sent_to['users'];
|
||||
$users = $users ? $users : [];
|
||||
$groups = $sent_to['groups'];
|
||||
|
||||
if ($users) {
|
||||
$users = UserManager::get_user_list_by_ids($users, true);
|
||||
}
|
||||
|
||||
if (!empty($groups)) {
|
||||
$groupUsers = GroupManager::get_groups_users($groups);
|
||||
$groupUsers = UserManager::get_user_list_by_ids($groupUsers, true);
|
||||
|
||||
if (!empty($groupUsers)) {
|
||||
$users = array_merge($users, $groupUsers);
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($users)) {
|
||||
if (!empty($this->logger)) {
|
||||
$this->logger->addInfo('User list is empty. No users found. Trying all_users()');
|
||||
}
|
||||
$users = self::all_users();
|
||||
}
|
||||
|
||||
// Clean users just in case
|
||||
$newListUsers = [];
|
||||
if (!empty($users)) {
|
||||
foreach ($users as $user) {
|
||||
$newListUsers[$user['user_id']] = ['user_id' => $user['user_id']];
|
||||
}
|
||||
}
|
||||
|
||||
return $newListUsers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Email subject.
|
||||
*
|
||||
* @param bool $directMessage
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function subject($directMessage = false)
|
||||
{
|
||||
if ($directMessage) {
|
||||
$result = $this->announcement('title');
|
||||
} else {
|
||||
$result = $this->course('title').' - '.$this->announcement('title');
|
||||
}
|
||||
|
||||
$result = stripslashes($result);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Email message.
|
||||
*
|
||||
* @param int $receiverUserId
|
||||
* @param bool $checkUrls It checks access url of user when multiple_access_urls = true
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function message($receiverUserId, $checkUrls = false)
|
||||
{
|
||||
$content = $this->announcement('content');
|
||||
$session_id = $this->session_id;
|
||||
$courseCode = $this->course('code');
|
||||
$courseId = $this->course('real_id');
|
||||
$content = AnnouncementManager::parseContent(
|
||||
$receiverUserId,
|
||||
$content,
|
||||
$courseCode,
|
||||
$session_id
|
||||
);
|
||||
|
||||
$accessConfig = [];
|
||||
$useMultipleUrl = api_get_configuration_value('multiple_access_urls');
|
||||
if ($useMultipleUrl && $checkUrls) {
|
||||
$accessUrls = api_get_access_url_from_user($receiverUserId, $courseId);
|
||||
if (!empty($accessUrls)) {
|
||||
$accessConfig['multiple_access_urls'] = true;
|
||||
$accessConfig['access_url'] = (int) $accessUrls[0];
|
||||
}
|
||||
}
|
||||
// Build the link by hand because api_get_cidreq() doesn't accept course params
|
||||
$course_param = 'cidReq='.$courseCode.'&id_session='.$session_id.'&gidReq='.api_get_group_id();
|
||||
$course_name = $this->course('title');
|
||||
$result = "<div>$content</div>";
|
||||
|
||||
// Adding attachment
|
||||
$attachment = $this->attachment();
|
||||
if (!empty($attachment)) {
|
||||
$result .= '<br />';
|
||||
$result .= Display::url(
|
||||
$attachment['filename'],
|
||||
api_get_path(WEB_CODE_PATH, $accessConfig).
|
||||
'announcements/download.php?file='.basename($attachment['path']).'&'.$course_param
|
||||
);
|
||||
$result .= '<br />';
|
||||
}
|
||||
|
||||
$result .= '<hr />';
|
||||
|
||||
$userInfo = api_get_user_info();
|
||||
if (!empty($userInfo)) {
|
||||
if ('true' === api_get_setting('show_email_addresses')) {
|
||||
$result .= '<a href="mailto:'.$userInfo['mail'].'">'.$userInfo['complete_name'].'</a><br/>';
|
||||
} else {
|
||||
$result .= '<p>'.$userInfo['complete_name'].'</p><br/>';
|
||||
}
|
||||
}
|
||||
|
||||
$result .= '<a href="'.api_get_path(WEB_CODE_PATH, $accessConfig).'announcements/announcements.php?'.$course_param.'">'.
|
||||
$course_name.'</a><br/>';
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the one file that can be attached to an announcement.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function attachment()
|
||||
{
|
||||
$result = [];
|
||||
$table = Database::get_course_table(TABLE_ANNOUNCEMENT_ATTACHMENT);
|
||||
$id = $this->announcement('id');
|
||||
$course_id = $this->course('real_id');
|
||||
$sql = "SELECT * FROM $table
|
||||
WHERE c_id = $course_id AND announcement_id = $id ";
|
||||
$rs = Database::query($sql);
|
||||
$course_path = $this->course('directory');
|
||||
while ($row = Database::fetch_array($rs)) {
|
||||
$path = api_get_path(SYS_COURSE_PATH).$course_path.'/upload/announcements/'.$row['path'];
|
||||
$filename = $row['filename'];
|
||||
$result[] = ['path' => $path, 'filename' => $filename];
|
||||
}
|
||||
|
||||
$result = $result ? reset($result) : [];
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send announcement by email to myself.
|
||||
*/
|
||||
public function sendAnnouncementEmailToMySelf()
|
||||
{
|
||||
$userId = api_get_user_id();
|
||||
$subject = $this->subject();
|
||||
$message = $this->message($userId);
|
||||
MessageManager::send_message_simple(
|
||||
$userId,
|
||||
$subject,
|
||||
$message,
|
||||
api_get_user_id(),
|
||||
false,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send emails to users.
|
||||
*
|
||||
* @param bool $sendToUsersInSession
|
||||
* @param bool $sendToDrhUsers send a copy of the message to the DRH users
|
||||
* @param int $senderId related to the main user
|
||||
* @param bool $directMessage
|
||||
* @param bool $checkUrls It checks access url of user when multiple_access_urls = true
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function send($sendToUsersInSession = false, $sendToDrhUsers = false, $senderId = 0, $directMessage = false, $checkUrls = false)
|
||||
{
|
||||
$senderId = empty($senderId) ? api_get_user_id() : (int) $senderId;
|
||||
$subject = $this->subject($directMessage);
|
||||
$courseId = $this->course('real_id');
|
||||
// Send email one by one to avoid antispam
|
||||
$users = $this->sent_to();
|
||||
|
||||
$batchSize = 20;
|
||||
$counter = 1;
|
||||
$em = Database::getManager();
|
||||
|
||||
if (empty($users) && !empty($this->logger)) {
|
||||
$this->logger->addInfo('User list is empty. No emails will be sent.');
|
||||
}
|
||||
$messageSentTo = [];
|
||||
foreach ($users as $user) {
|
||||
$message = $this->message($user['user_id'], $checkUrls);
|
||||
$wasSent = MessageManager::messageWasAlreadySent($senderId, $user['user_id'], $subject, $message);
|
||||
if ($wasSent === false) {
|
||||
if (!empty($this->logger)) {
|
||||
$this->logger->addInfo(
|
||||
'Announcement: #'.$this->announcement('id').'. Send email to user: #'.$user['user_id']
|
||||
);
|
||||
}
|
||||
|
||||
$messageSentTo[] = $user['user_id'];
|
||||
MessageManager::send_message_simple(
|
||||
$user['user_id'],
|
||||
$subject,
|
||||
$message,
|
||||
$senderId,
|
||||
$sendToDrhUsers,
|
||||
true,
|
||||
[],
|
||||
true,
|
||||
[],
|
||||
$checkUrls,
|
||||
$courseId
|
||||
);
|
||||
} else {
|
||||
if (!empty($this->logger)) {
|
||||
$this->logger->addInfo(
|
||||
'Message "'.$subject.'" was already sent. Announcement: #'.$this->announcement('id').'.
|
||||
User: #'.$user['user_id']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (($counter % $batchSize) === 0) {
|
||||
$em->flush();
|
||||
$em->clear();
|
||||
}
|
||||
$counter++;
|
||||
}
|
||||
|
||||
if ($sendToUsersInSession) {
|
||||
$sessionList = SessionManager::get_session_by_course($this->course['real_id']);
|
||||
if (!empty($sessionList)) {
|
||||
foreach ($sessionList as $sessionInfo) {
|
||||
$sessionId = $sessionInfo['id'];
|
||||
$message = $this->message(null);
|
||||
$userList = CourseManager::get_user_list_from_course_code(
|
||||
$this->course['code'],
|
||||
$sessionId
|
||||
);
|
||||
if (!empty($userList)) {
|
||||
foreach ($userList as $user) {
|
||||
$messageSentTo[] = $user['user_id'];
|
||||
MessageManager::send_message_simple(
|
||||
$user['user_id'],
|
||||
$subject,
|
||||
$message,
|
||||
$senderId,
|
||||
false,
|
||||
true,
|
||||
[],
|
||||
true,
|
||||
[],
|
||||
$checkUrls,
|
||||
$courseId
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->logMailSent();
|
||||
$messageSentTo = array_unique($messageSentTo);
|
||||
|
||||
return $messageSentTo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store that emails where sent.
|
||||
*/
|
||||
public function logMailSent()
|
||||
{
|
||||
$id = $this->announcement('id');
|
||||
$courseId = $this->course('real_id');
|
||||
$table = Database::get_course_table(TABLE_ANNOUNCEMENT);
|
||||
$sql = "UPDATE $table SET
|
||||
email_sent = 1
|
||||
WHERE
|
||||
c_id = $courseId AND
|
||||
id = $id AND
|
||||
session_id = {$this->session_id}
|
||||
";
|
||||
Database::query($sql);
|
||||
}
|
||||
}
|
||||
2282
main/inc/lib/AnnouncementManager.php
Normal file
2282
main/inc/lib/AnnouncementManager.php
Normal file
File diff suppressed because it is too large
Load Diff
402
main/inc/lib/Compilatio.php
Normal file
402
main/inc/lib/Compilatio.php
Normal file
@@ -0,0 +1,402 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Psr7\Utils;
|
||||
|
||||
/**
|
||||
* Build the communication with the SOAP server Compilatio.net
|
||||
* call several methods for the file management in Compilatio.net.
|
||||
*
|
||||
* @version: 2.0
|
||||
*/
|
||||
class Compilatio
|
||||
{
|
||||
/** Identification key for the Compilatio account*/
|
||||
public $key;
|
||||
|
||||
/**
|
||||
* @var Client
|
||||
*/
|
||||
public $client;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $baseUrl;
|
||||
/** Webservice connection*/
|
||||
private $maxFileSize;
|
||||
private $proxyHost;
|
||||
private $proxyPort;
|
||||
|
||||
/**
|
||||
* Compilatio constructor.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$settings = $this->getSettings();
|
||||
|
||||
$this->maxFileSize = $settings['max_filesize'];
|
||||
$this->key = $settings['key'];
|
||||
$this->baseUrl = $settings['api_url'];
|
||||
|
||||
if (!empty($settings['proxy_host'])) {
|
||||
$this->proxyHost = $settings['proxy_host'];
|
||||
$this->proxyPort = $settings['proxy_port'];
|
||||
}
|
||||
|
||||
$clientConfig = [
|
||||
'base_uri' => api_remove_trailing_slash($this->baseUrl).'/',
|
||||
'headers' => [
|
||||
'X-Auth-Token' => $this->key,
|
||||
'Accept' => 'application/json',
|
||||
],
|
||||
];
|
||||
|
||||
if ($this->proxyPort) {
|
||||
$clientConfig['proxy'] = $this->proxyHost.':'.$this->proxyPort;
|
||||
}
|
||||
|
||||
$this->client = new Client($clientConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getKey()
|
||||
{
|
||||
return $this->key;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $key
|
||||
*
|
||||
* @return Compilatio
|
||||
*/
|
||||
public function setKey($key)
|
||||
{
|
||||
$this->key = $key;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getMaxFileSize()
|
||||
{
|
||||
return $this->maxFileSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getProxyHost()
|
||||
{
|
||||
return $this->proxyHost;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getProxyPort()
|
||||
{
|
||||
return $this->proxyPort;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for the file load.
|
||||
*/
|
||||
public function sendDoc(
|
||||
string $title,
|
||||
string $description,
|
||||
string $filename,
|
||||
string $filepath
|
||||
) {
|
||||
$user = api_get_user_entity(api_get_user_id());
|
||||
|
||||
$postData = [
|
||||
'folder_id' => '',
|
||||
'title' => $title,
|
||||
'filename' => basename($filename),
|
||||
'indexed' => 'true',
|
||||
'user_notes' => [
|
||||
'description' => $description,
|
||||
],
|
||||
'authors' => [
|
||||
[
|
||||
'firstname' => $user->getFirstname(),
|
||||
'lastname' => $user->getlastname(),
|
||||
'email_address' => $user->getEmail(),
|
||||
],
|
||||
],
|
||||
'depositor' => [
|
||||
'firstname' => $user->getFirstname(),
|
||||
'lastname' => $user->getlastname(),
|
||||
'email_address' => $user->getEmail(),
|
||||
],
|
||||
];
|
||||
|
||||
try {
|
||||
$responseBody = $this->client
|
||||
->post(
|
||||
'private/documents',
|
||||
[
|
||||
'multipart' => [
|
||||
[
|
||||
'name' => 'postData',
|
||||
'contents' => json_encode($postData),
|
||||
],
|
||||
[
|
||||
'name' => 'file',
|
||||
'contents' => Utils::tryFopen($filepath, 'r'),
|
||||
],
|
||||
],
|
||||
]
|
||||
)
|
||||
->getBody()
|
||||
;
|
||||
} catch (Exception $e) {
|
||||
throw new Exception($e->getMessage());
|
||||
}
|
||||
|
||||
$body = json_decode((string) $responseBody, true);
|
||||
|
||||
return $body['data']['document']['id'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for recover a document's information.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getDoc(string $documentId): array
|
||||
{
|
||||
try {
|
||||
$responseBody = $this->client
|
||||
->get(
|
||||
"private/documents/$documentId"
|
||||
)
|
||||
->getBody()
|
||||
;
|
||||
} catch (Exception $e) {
|
||||
throw new Exception($e->getMessage());
|
||||
}
|
||||
|
||||
$responseJson = json_decode((string) $responseBody, true);
|
||||
$dataDocument = $responseJson['data']['document'];
|
||||
|
||||
$documentInfo = [
|
||||
'report_url' => $dataDocument['report_url'],
|
||||
];
|
||||
// anasim analyse type is applied for services Magister and Copyright
|
||||
// anasim-premium analyse type is applied for services Magister+ and Copyright+
|
||||
$anasim = 'anasim';
|
||||
if (isset($dataDocument['analyses']['anasim-premium'])) {
|
||||
$anasim = 'anasim-premium';
|
||||
if (isset($dataDocument['analyses']['anasim'])) {
|
||||
if (isset($dataDocument['analyses']['anasim']['creation_launch_date']) && isset($dataDocument['analyses']['anasim-premium']['creation_launch_date'])) {
|
||||
// if the 2 analyses type exist (which could happen technically but would be exceptional) then we present the most recent one.
|
||||
if ($dataDocument['analyses']['anasim']['creation_launch_date'] > $dataDocument['analyses']['anasim-premium']['creation_launch_date']) {
|
||||
$anasim = 'anasim';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isset($dataDocument['analyses'][$anasim]['state'])) {
|
||||
$documentInfo['analysis_status'] = $dataDocument['analyses'][$anasim]['state'];
|
||||
}
|
||||
|
||||
if (isset($dataDocument['light_reports'][$anasim]['scores']['global_score_percent'])) {
|
||||
$documentInfo['report_percent'] = $dataDocument['light_reports'][$anasim]['scores']['global_score_percent'];
|
||||
}
|
||||
|
||||
return $documentInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for deleting a Compialtio's account document.
|
||||
*/
|
||||
public function deldoc(string $documentId)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for start the analysis for a document.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function startAnalyse(string $compilatioId): string
|
||||
{
|
||||
try {
|
||||
$responseBody = $this->client
|
||||
->post(
|
||||
'private/analyses',
|
||||
[
|
||||
'json' => [
|
||||
'doc_id' => $compilatioId,
|
||||
],
|
||||
]
|
||||
)
|
||||
->getBody()
|
||||
;
|
||||
} catch (Exception $e) {
|
||||
throw new Exception($e->getMessage());
|
||||
}
|
||||
|
||||
$body = json_decode((string) $responseBody, true);
|
||||
|
||||
return $body['data']['analysis']['state'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for identify a file extension and the possibility that the document can be managed by Compilatio.
|
||||
*/
|
||||
public static function verifiFileType(string $filename): bool
|
||||
{
|
||||
$types = ['doc', 'docx', 'rtf', 'xls', 'xlsx', 'ppt', 'pptx', 'odt', 'pdf', 'txt', 'htm', 'html'];
|
||||
$extension = substr($filename, strrpos($filename, '.') + 1);
|
||||
$extension = strtolower($extension);
|
||||
|
||||
return in_array($extension, $types);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for display the PomprseuilmankBar (% de plagiat).
|
||||
*/
|
||||
public static function getPomprankBarv31(
|
||||
int $index,
|
||||
int $weakThreshold,
|
||||
int $highThreshold
|
||||
): string {
|
||||
$index = round($index);
|
||||
$class = 'danger';
|
||||
if ($index < $weakThreshold) {
|
||||
$class = 'success';
|
||||
} elseif ($index < $highThreshold) {
|
||||
$class = 'warning';
|
||||
}
|
||||
|
||||
return Display::bar_progress($index, true, null, $class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for delete a document of the compilatio table if plagiarismTool is Compilatio.
|
||||
*/
|
||||
public static function plagiarismDeleteDoc(int $courseId, int $itemId)
|
||||
{
|
||||
if (api_get_configuration_value('allow_compilatio_tool') !== false) {
|
||||
$table = Database::get_course_table(TABLE_PLAGIARISM);
|
||||
$params = [$courseId, $itemId];
|
||||
Database::delete($table, ['c_id = ? AND document_id = ?' => $params]);
|
||||
}
|
||||
}
|
||||
|
||||
public function saveDocument(int $courseId, int $documentId, string $compilatioId)
|
||||
{
|
||||
$table = Database::get_course_table(TABLE_PLAGIARISM);
|
||||
$params = [
|
||||
'c_id' => $courseId,
|
||||
'document_id' => $documentId,
|
||||
'compilatio_id' => $compilatioId,
|
||||
];
|
||||
Database::insert($table, $params);
|
||||
}
|
||||
|
||||
public function getCompilatioId(int $documentId, int $courseId): ?string
|
||||
{
|
||||
$table = Database::get_course_table(TABLE_PLAGIARISM);
|
||||
$sql = "SELECT compilatio_id FROM $table
|
||||
WHERE document_id = $documentId AND c_id= $courseId";
|
||||
$result = Database::query($sql);
|
||||
$result = Database::fetch_object($result);
|
||||
|
||||
return $result ? (string) $result->compilatio_id : null;
|
||||
}
|
||||
|
||||
public function giveWorkIdState(int $workId): string
|
||||
{
|
||||
$courseId = api_get_course_int_id();
|
||||
$compilatioId = $this->getCompilatioId($workId, $courseId);
|
||||
|
||||
$actionCompilatio = '';
|
||||
// if the compilatio's hash is not a valide hash md5,
|
||||
// we return à specific status (cf : IsInCompilatio() )
|
||||
// Not used since implementation of RestAPI but there if needed later
|
||||
//$actionCompilatio = get_lang('CompilatioDocumentTextNotImage').'<br/>'.
|
||||
// get_lang('CompilatioDocumentNotCorrupt');
|
||||
$status = '';
|
||||
if (!empty($compilatioId)) {
|
||||
// if compilatio_id is a hash md5, we call the function of the compilatio's
|
||||
// webservice who return the document's status
|
||||
$soapRes = $this->getDoc($compilatioId);
|
||||
$status = $soapRes['analysis_status'] ?? '';
|
||||
|
||||
$spinnerIcon = Display::returnFontAwesomeIcon('spinner', null, true, 'fa-spin');
|
||||
|
||||
switch ($status) {
|
||||
case 'finished':
|
||||
$actionCompilatio .= self::getPomprankBarv31($soapRes['report_percent'], 10, 35)
|
||||
.PHP_EOL
|
||||
.Display::url(
|
||||
get_lang('CompilatioAnalysis'),
|
||||
$soapRes['report_url'],
|
||||
['class' => 'btn btn-primary btn-xs', 'target' => '_blank']
|
||||
);
|
||||
break;
|
||||
case 'running':
|
||||
$actionCompilatio .= "<div style='font-weight:bold;text-align:left'>"
|
||||
.get_lang('CompilatioAnalysisInProgress')
|
||||
."</div>";
|
||||
$actionCompilatio .= "<div style='font-size:80%;font-style:italic;margin-bottom:5px;'>"
|
||||
.get_lang('CompilatioAnalysisPercentage')
|
||||
."</div>";
|
||||
$actionCompilatio .= $spinnerIcon.PHP_EOL.get_lang('CompilatioAnalysisEnding');
|
||||
break;
|
||||
case 'waiting':
|
||||
$actionCompilatio .= $spinnerIcon.PHP_EOL.get_lang('CompilatioWaitingAnalysis');
|
||||
break;
|
||||
case 'canceled':
|
||||
$actionCompilatio .= get_lang('Cancelled');
|
||||
break;
|
||||
case 'scheduled':
|
||||
$actionCompilatio .= $spinnerIcon.PHP_EOL.get_lang('CompilatioAwaitingAnalysis');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $workId.'|'.$actionCompilatio.'|'.$status.'|';
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function getSettings(): array
|
||||
{
|
||||
if (empty(api_get_configuration_value('allow_compilatio_tool')) ||
|
||||
empty(api_get_configuration_value('compilatio_tool'))
|
||||
) {
|
||||
throw new Exception('Compilatio not available');
|
||||
}
|
||||
|
||||
$compilatioTool = api_get_configuration_value('compilatio_tool');
|
||||
|
||||
if (!isset($compilatioTool['settings'])) {
|
||||
throw new Exception('Compilatio config available');
|
||||
}
|
||||
|
||||
$settings = $compilatioTool['settings'];
|
||||
|
||||
if (empty($settings['key'])) {
|
||||
throw new Exception('API key not available');
|
||||
}
|
||||
|
||||
if (empty($settings['api_url'])) {
|
||||
throw new Exception('Api URL not available');
|
||||
}
|
||||
|
||||
return $settings;
|
||||
}
|
||||
}
|
||||
887
main/inc/lib/CourseChatUtils.php
Normal file
887
main/inc/lib/CourseChatUtils.php
Normal file
@@ -0,0 +1,887 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use Chamilo\CoreBundle\Entity\Course;
|
||||
use Chamilo\CoreBundle\Entity\CourseRelUser;
|
||||
use Chamilo\CoreBundle\Entity\Session;
|
||||
use Chamilo\CoreBundle\Entity\SessionRelCourseRelUser;
|
||||
use Chamilo\CourseBundle\Entity\CChatConnected;
|
||||
use Chamilo\UserBundle\Entity\User;
|
||||
use Doctrine\Common\Collections\Criteria;
|
||||
use Michelf\MarkdownExtra;
|
||||
|
||||
/**
|
||||
* Class CourseChat
|
||||
* Manage the chat for a course.
|
||||
*/
|
||||
class CourseChatUtils
|
||||
{
|
||||
private $groupId;
|
||||
private $courseId;
|
||||
private $sessionId;
|
||||
private $userId;
|
||||
|
||||
/**
|
||||
* CourseChat constructor.
|
||||
*
|
||||
* @param int $courseId
|
||||
* @param int $userId
|
||||
* @param int $sessionId
|
||||
* @param int $groupId
|
||||
*/
|
||||
public function __construct($courseId, $userId, $sessionId = 0, $groupId = 0)
|
||||
{
|
||||
$this->courseId = (int) $courseId;
|
||||
$this->userId = (int) $userId;
|
||||
$this->sessionId = (int) $sessionId;
|
||||
$this->groupId = (int) $groupId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare a message. Clean and insert emojis.
|
||||
*
|
||||
* @param string $message The message to prepare
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function prepareMessage($message)
|
||||
{
|
||||
if (empty($message)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
Emojione\Emojione::$imagePathPNG = api_get_path(WEB_LIBRARY_PATH).'javascript/emojione/png/';
|
||||
Emojione\Emojione::$ascii = true;
|
||||
|
||||
$message = trim($message);
|
||||
$message = nl2br($message);
|
||||
// Security XSS
|
||||
$message = Security::remove_XSS($message);
|
||||
//search urls
|
||||
$message = preg_replace(
|
||||
'@((https?://)?([-\w]+\.[-\w\.]+)+\w(:\d+)?(/([-\w/_\.]*(\?\S+)?)?)*)@',
|
||||
'<a href="$1" target="_blank">$1</a>',
|
||||
$message
|
||||
);
|
||||
// add "http://" if not set
|
||||
$message = preg_replace(
|
||||
'/<a\s[^>]*href\s*=\s*"((?!https?:\/\/)[^"]*)"[^>]*>/i',
|
||||
'<a href="http://$1" target="_blank">',
|
||||
$message
|
||||
);
|
||||
// Parsing emojis
|
||||
$message = Emojione\Emojione::toImage($message);
|
||||
// Parsing text to understand markdown (code highlight)
|
||||
$message = MarkdownExtra::defaultTransform($message);
|
||||
|
||||
return $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save a chat message in a HTML file.
|
||||
*
|
||||
* @param string $message
|
||||
* @param int $friendId
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function saveMessage($message, $friendId = 0)
|
||||
{
|
||||
if (empty($message)) {
|
||||
return false;
|
||||
}
|
||||
$friendId = (int) $friendId;
|
||||
|
||||
$userInfo = api_get_user_info($this->userId);
|
||||
$courseInfo = api_get_course_info_by_id($this->courseId);
|
||||
$isMaster = api_is_course_admin();
|
||||
$document_path = api_get_path(SYS_COURSE_PATH).$courseInfo['path'].'/document';
|
||||
$basepath_chat = '/chat_files';
|
||||
$group_info = [];
|
||||
if ($this->groupId) {
|
||||
$group_info = GroupManager::get_group_properties($this->groupId);
|
||||
$basepath_chat = $group_info['directory'].'/chat_files';
|
||||
}
|
||||
|
||||
$chat_path = $document_path.$basepath_chat.'/';
|
||||
|
||||
if (!is_dir($chat_path)) {
|
||||
if (is_file($chat_path)) {
|
||||
@unlink($chat_path);
|
||||
}
|
||||
}
|
||||
|
||||
$date_now = date('Y-m-d');
|
||||
$timeNow = date('d/m/y H:i:s');
|
||||
$basename_chat = 'messages-'.$date_now;
|
||||
|
||||
if ($this->groupId && !$friendId) {
|
||||
$basename_chat = 'messages-'.$date_now.'_gid-'.$this->groupId;
|
||||
} elseif ($this->sessionId && !$friendId) {
|
||||
$basename_chat = 'messages-'.$date_now.'_sid-'.$this->sessionId;
|
||||
} elseif ($friendId) {
|
||||
if ($this->userId < $friendId) {
|
||||
$basename_chat = 'messages-'.$date_now.'_uid-'.$this->userId.'-'.$friendId;
|
||||
} else {
|
||||
$basename_chat = 'messages-'.$date_now.'_uid-'.$friendId.'-'.$this->userId;
|
||||
}
|
||||
}
|
||||
|
||||
$message = self::prepareMessage($message);
|
||||
|
||||
$fileTitle = $basename_chat.'.log.html';
|
||||
$filePath = $basepath_chat.'/'.$fileTitle;
|
||||
$absoluteFilePath = $chat_path.$fileTitle;
|
||||
|
||||
if (!file_exists($absoluteFilePath)) {
|
||||
$doc_id = add_document(
|
||||
$courseInfo,
|
||||
$filePath,
|
||||
'file',
|
||||
0,
|
||||
$fileTitle,
|
||||
null,
|
||||
0,
|
||||
true,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
false
|
||||
);
|
||||
$documentLogTypes = ['DocumentAdded', 'invisible'];
|
||||
foreach ($documentLogTypes as $logType) {
|
||||
api_item_property_update(
|
||||
$courseInfo,
|
||||
TOOL_DOCUMENT,
|
||||
$doc_id,
|
||||
$logType,
|
||||
$this->userId,
|
||||
$group_info,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
$this->sessionId
|
||||
);
|
||||
}
|
||||
|
||||
item_property_update_on_folder($courseInfo, $basepath_chat, $this->userId);
|
||||
} else {
|
||||
$doc_id = DocumentManager::get_document_id($courseInfo, $filePath);
|
||||
}
|
||||
|
||||
$fp = fopen($absoluteFilePath, 'a');
|
||||
$userPhoto = UserManager::getUserPicture($this->userId, USER_IMAGE_SIZE_MEDIUM, true, $userInfo);
|
||||
|
||||
if ($isMaster) {
|
||||
$fileContent = '
|
||||
<div class="message-teacher">
|
||||
<div class="content-message">
|
||||
<div class="chat-message-block-name">'.$userInfo['complete_name'].'</div>
|
||||
<div class="chat-message-block-content">'.$message.'</div>
|
||||
<div class="message-date">'.$timeNow.'</div>
|
||||
</div>
|
||||
<div class="icon-message"></div>
|
||||
<img class="chat-image" src="'.$userPhoto.'">
|
||||
</div>
|
||||
';
|
||||
} else {
|
||||
$fileContent = '
|
||||
<div class="message-student">
|
||||
<img class="chat-image" src="'.$userPhoto.'">
|
||||
<div class="icon-message"></div>
|
||||
<div class="content-message">
|
||||
<div class="chat-message-block-name">'.$userInfo['complete_name'].'</div>
|
||||
<div class="chat-message-block-content">'.$message.'</div>
|
||||
<div class="message-date">'.$timeNow.'</div>
|
||||
</div>
|
||||
</div>
|
||||
';
|
||||
}
|
||||
|
||||
fputs($fp, $fileContent);
|
||||
fclose($fp);
|
||||
$size = filesize($absoluteFilePath);
|
||||
update_existing_document($courseInfo, $doc_id, $size);
|
||||
item_property_update_on_folder($courseInfo, $basepath_chat, $this->userId);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect a user from course chats.
|
||||
*
|
||||
* @param int $userId
|
||||
*/
|
||||
public static function exitChat($userId)
|
||||
{
|
||||
$listCourse = CourseManager::get_courses_list_by_user_id($userId);
|
||||
|
||||
foreach ($listCourse as $course) {
|
||||
Database::getManager()
|
||||
->createQuery('
|
||||
DELETE FROM ChamiloCourseBundle:CChatConnected ccc
|
||||
WHERE ccc.cId = :course AND ccc.userId = :user
|
||||
')
|
||||
->execute([
|
||||
'course' => intval($course['real_id']),
|
||||
'user' => intval($userId),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect users who are more than 5 seconds inactive.
|
||||
*/
|
||||
public function disconnectInactiveUsers()
|
||||
{
|
||||
$em = Database::getManager();
|
||||
$extraCondition = "AND ccc.toGroupId = {$this->groupId}";
|
||||
if (empty($this->groupId)) {
|
||||
$extraCondition = "AND ccc.sessionId = {$this->sessionId}";
|
||||
}
|
||||
|
||||
$connectedUsers = $em
|
||||
->createQuery("
|
||||
SELECT ccc FROM ChamiloCourseBundle:CChatConnected ccc
|
||||
WHERE ccc.cId = :course $extraCondition
|
||||
")
|
||||
->setParameter('course', $this->courseId)
|
||||
->getResult();
|
||||
|
||||
$now = new DateTime(api_get_utc_datetime(), new DateTimeZone('UTC'));
|
||||
$cd_count_time_seconds = $now->getTimestamp();
|
||||
/** @var CChatConnected $connection */
|
||||
foreach ($connectedUsers as $connection) {
|
||||
$date_count_time_seconds = $connection->getLastConnection()->getTimestamp();
|
||||
if (strcmp($now->format('Y-m-d'), $connection->getLastConnection()->format('Y-m-d')) !== 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (($cd_count_time_seconds - $date_count_time_seconds) <= 5) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$em
|
||||
->createQuery('
|
||||
DELETE FROM ChamiloCourseBundle:CChatConnected ccc
|
||||
WHERE ccc.cId = :course AND ccc.userId = :user AND ccc.toGroupId = :group
|
||||
')
|
||||
->execute([
|
||||
'course' => $this->courseId,
|
||||
'user' => $connection->getUserId(),
|
||||
'group' => $this->groupId,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Keep registered to a user as connected.
|
||||
*/
|
||||
public function keepUserAsConnected()
|
||||
{
|
||||
$em = Database::getManager();
|
||||
$extraCondition = null;
|
||||
|
||||
if ($this->groupId) {
|
||||
$extraCondition = 'AND ccc.toGroupId = '.intval($this->groupId);
|
||||
} else {
|
||||
$extraCondition = 'AND ccc.sessionId = '.intval($this->sessionId);
|
||||
}
|
||||
|
||||
$currentTime = new DateTime(api_get_utc_datetime(), new DateTimeZone('UTC'));
|
||||
|
||||
$connection = $em
|
||||
->createQuery("
|
||||
SELECT ccc FROM ChamiloCourseBundle:CChatConnected ccc
|
||||
WHERE ccc.userId = :user AND ccc.cId = :course $extraCondition
|
||||
")
|
||||
->setParameters([
|
||||
'user' => $this->userId,
|
||||
'course' => $this->courseId,
|
||||
])
|
||||
->getOneOrNullResult();
|
||||
|
||||
if ($connection) {
|
||||
$connection->setLastConnection($currentTime);
|
||||
$em->merge($connection);
|
||||
$em->flush();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$connection = new CChatConnected();
|
||||
$connection
|
||||
->setCId($this->courseId)
|
||||
->setUserId($this->userId)
|
||||
->setLastConnection($currentTime)
|
||||
->setSessionId($this->sessionId)
|
||||
->setToGroupId($this->groupId);
|
||||
|
||||
$em->persist($connection);
|
||||
$em->flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the emoji allowed on course chat.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getEmojiStrategy()
|
||||
{
|
||||
return require_once api_get_path(SYS_CODE_PATH).'chat/emoji_strategy.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the emoji list to include in chat.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getEmojisToInclude()
|
||||
{
|
||||
return [
|
||||
':bowtie:',
|
||||
':smile:' |
|
||||
':laughing:',
|
||||
':blush:',
|
||||
':smiley:',
|
||||
':relaxed:',
|
||||
':smirk:',
|
||||
':heart_eyes:',
|
||||
':kissing_heart:',
|
||||
':kissing_closed_eyes:',
|
||||
':flushed:',
|
||||
':relieved:',
|
||||
':satisfied:',
|
||||
':grin:',
|
||||
':wink:',
|
||||
':stuck_out_tongue_winking_eye:',
|
||||
':stuck_out_tongue_closed_eyes:',
|
||||
':grinning:',
|
||||
':kissing:',
|
||||
':kissing_smiling_eyes:',
|
||||
':stuck_out_tongue:',
|
||||
':sleeping:',
|
||||
':worried:',
|
||||
':frowning:',
|
||||
':anguished:',
|
||||
':open_mouth:',
|
||||
':grimacing:',
|
||||
':confused:',
|
||||
':hushed:',
|
||||
':expressionless:',
|
||||
':unamused:',
|
||||
':sweat_smile:',
|
||||
':sweat:',
|
||||
':disappointed_relieved:',
|
||||
':weary:',
|
||||
':pensive:',
|
||||
':disappointed:',
|
||||
':confounded:',
|
||||
':fearful:',
|
||||
':cold_sweat:',
|
||||
':persevere:',
|
||||
':cry:',
|
||||
':sob:',
|
||||
':joy:',
|
||||
':astonished:',
|
||||
':scream:',
|
||||
':neckbeard:',
|
||||
':tired_face:',
|
||||
':angry:',
|
||||
':rage:',
|
||||
':triumph:',
|
||||
':sleepy:',
|
||||
':yum:',
|
||||
':mask:',
|
||||
':sunglasses:',
|
||||
':dizzy_face:',
|
||||
':imp:',
|
||||
':smiling_imp:',
|
||||
':neutral_face:',
|
||||
':no_mouth:',
|
||||
':innocent:',
|
||||
':alien:',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the chat history file name.
|
||||
*
|
||||
* @param bool $absolute Optional. Whether get the base or the absolute file path
|
||||
* @param int $friendId optional
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFileName($absolute = false, $friendId = 0)
|
||||
{
|
||||
$date = date('Y-m-d');
|
||||
$base = 'messages-'.$date.'.log.html';
|
||||
|
||||
if ($this->groupId && !$friendId) {
|
||||
$base = 'messages-'.$date.'_gid-'.$this->groupId.'.log.html';
|
||||
} elseif ($this->sessionId && !$friendId) {
|
||||
$base = 'messages-'.$date.'_sid-'.$this->sessionId.'.log.html';
|
||||
} elseif ($friendId) {
|
||||
if ($this->userId < $friendId) {
|
||||
$base = 'messages-'.$date.'_uid-'.$this->userId.'-'.$friendId.'.log.html';
|
||||
} else {
|
||||
$base = 'messages-'.$date.'_uid-'.$friendId.'-'.$this->userId.'.log.html';
|
||||
}
|
||||
}
|
||||
|
||||
if (!$absolute) {
|
||||
return $base;
|
||||
}
|
||||
|
||||
$courseInfo = api_get_course_info_by_id($this->courseId);
|
||||
$document_path = api_get_path(SYS_COURSE_PATH).$courseInfo['path'].'/document';
|
||||
$chatPath = $document_path.'/chat_files/';
|
||||
|
||||
if ($this->groupId) {
|
||||
$group_info = GroupManager::get_group_properties($this->groupId);
|
||||
$chatPath = $document_path.$group_info['directory'].'/chat_files/';
|
||||
}
|
||||
|
||||
return $chatPath.$base;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the chat history.
|
||||
*
|
||||
* @param bool $reset
|
||||
* @param int $friendId optional
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function readMessages($reset = false, $friendId = 0)
|
||||
{
|
||||
$courseInfo = api_get_course_info_by_id($this->courseId);
|
||||
$date_now = date('Y-m-d');
|
||||
$isMaster = (bool) api_is_course_admin();
|
||||
$basepath_chat = '/chat_files';
|
||||
$document_path = api_get_path(SYS_COURSE_PATH).$courseInfo['path'].'/document';
|
||||
$group_info = [];
|
||||
if ($this->groupId) {
|
||||
$group_info = GroupManager::get_group_properties($this->groupId);
|
||||
$basepath_chat = $group_info['directory'].'/chat_files';
|
||||
}
|
||||
|
||||
$chat_path = $document_path.$basepath_chat.'/';
|
||||
|
||||
if (!is_dir($chat_path)) {
|
||||
if (is_file($chat_path)) {
|
||||
@unlink($chat_path);
|
||||
}
|
||||
|
||||
if (!api_is_anonymous()) {
|
||||
@mkdir($chat_path, api_get_permissions_for_new_directories());
|
||||
// Save chat files document for group into item property
|
||||
if ($this->groupId) {
|
||||
$doc_id = add_document(
|
||||
$courseInfo,
|
||||
$basepath_chat,
|
||||
'folder',
|
||||
0,
|
||||
'chat_files',
|
||||
null,
|
||||
0,
|
||||
true,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
false
|
||||
);
|
||||
api_item_property_update(
|
||||
$courseInfo,
|
||||
TOOL_DOCUMENT,
|
||||
$doc_id,
|
||||
'FolderCreated',
|
||||
null,
|
||||
$group_info,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
);
|
||||
api_item_property_update(
|
||||
$courseInfo,
|
||||
TOOL_DOCUMENT,
|
||||
$doc_id,
|
||||
'invisible',
|
||||
null,
|
||||
$group_info,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$filename_chat = 'messages-'.$date_now.'.log.html';
|
||||
|
||||
if ($this->groupId && !$friendId) {
|
||||
$filename_chat = 'messages-'.$date_now.'_gid-'.$this->groupId.'.log.html';
|
||||
} elseif ($this->sessionId && !$friendId) {
|
||||
$filename_chat = 'messages-'.$date_now.'_sid-'.$this->sessionId.'.log.html';
|
||||
} elseif ($friendId) {
|
||||
if ($this->userId < $friendId) {
|
||||
$filename_chat = 'messages-'.$date_now.'_uid-'.$this->userId.'-'.$friendId.'.log.html';
|
||||
} else {
|
||||
$filename_chat = 'messages-'.$date_now.'_uid-'.$friendId.'-'.$this->userId.'.log.html';
|
||||
}
|
||||
}
|
||||
|
||||
if (!file_exists($chat_path.$filename_chat)) {
|
||||
@fclose(fopen($chat_path.$filename_chat, 'w'));
|
||||
if (!api_is_anonymous()) {
|
||||
$doc_id = add_document(
|
||||
$courseInfo,
|
||||
$basepath_chat.'/'.$filename_chat,
|
||||
'file',
|
||||
0,
|
||||
$filename_chat,
|
||||
null,
|
||||
0,
|
||||
true,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
false
|
||||
);
|
||||
if ($doc_id) {
|
||||
api_item_property_update(
|
||||
$courseInfo,
|
||||
TOOL_DOCUMENT,
|
||||
$doc_id,
|
||||
'DocumentAdded',
|
||||
$this->userId,
|
||||
$group_info,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
$this->sessionId
|
||||
);
|
||||
api_item_property_update(
|
||||
$courseInfo,
|
||||
TOOL_DOCUMENT,
|
||||
$doc_id,
|
||||
'invisible',
|
||||
$this->userId,
|
||||
$group_info,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
$this->sessionId
|
||||
);
|
||||
item_property_update_on_folder($courseInfo, $basepath_chat, $this->userId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$basename_chat = 'messages-'.$date_now;
|
||||
if ($this->groupId && !$friendId) {
|
||||
$basename_chat = 'messages-'.$date_now.'_gid-'.$this->groupId;
|
||||
} elseif ($this->sessionId && !$friendId) {
|
||||
$basename_chat = 'messages-'.$date_now.'_sid-'.$this->sessionId;
|
||||
} elseif ($friendId) {
|
||||
if ($this->userId < $friendId) {
|
||||
$basename_chat = 'messages-'.$date_now.'_uid-'.$this->userId.'-'.$friendId;
|
||||
} else {
|
||||
$basename_chat = 'messages-'.$date_now.'_uid-'.$friendId.'-'.$this->userId;
|
||||
}
|
||||
}
|
||||
|
||||
if ($reset && $isMaster) {
|
||||
$i = 1;
|
||||
while (file_exists($chat_path.$basename_chat.'-'.$i.'.log.html')) {
|
||||
$i++;
|
||||
}
|
||||
|
||||
@rename($chat_path.$basename_chat.'.log.html', $chat_path.$basename_chat.'-'.$i.'.log.html');
|
||||
@fclose(fopen($chat_path.$basename_chat.'.log.html', 'w'));
|
||||
|
||||
$doc_id = add_document(
|
||||
$courseInfo,
|
||||
$basepath_chat.'/'.$basename_chat.'-'.$i.'.log.html',
|
||||
'file',
|
||||
filesize($chat_path.$basename_chat.'-'.$i.'.log.html'),
|
||||
$basename_chat.'-'.$i.'.log.html',
|
||||
null,
|
||||
0,
|
||||
true,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
false
|
||||
);
|
||||
|
||||
api_item_property_update(
|
||||
$courseInfo,
|
||||
TOOL_DOCUMENT,
|
||||
$doc_id,
|
||||
'DocumentAdded',
|
||||
$this->userId,
|
||||
$group_info,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
$this->sessionId
|
||||
);
|
||||
api_item_property_update(
|
||||
$courseInfo,
|
||||
TOOL_DOCUMENT,
|
||||
$doc_id,
|
||||
'invisible',
|
||||
$this->userId,
|
||||
$group_info,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
$this->sessionId
|
||||
);
|
||||
item_property_update_on_folder($courseInfo, $basepath_chat, $this->userId);
|
||||
$doc_id = DocumentManager::get_document_id(
|
||||
$courseInfo,
|
||||
$basepath_chat.'/'.$basename_chat.'.log.html'
|
||||
);
|
||||
update_existing_document($courseInfo, $doc_id, 0);
|
||||
}
|
||||
|
||||
$remove = 0;
|
||||
$content = [];
|
||||
|
||||
if (file_exists($chat_path.$basename_chat.'.log.html')) {
|
||||
$content = file($chat_path.$basename_chat.'.log.html');
|
||||
$nbr_lines = sizeof($content);
|
||||
$remove = $nbr_lines - 100;
|
||||
}
|
||||
|
||||
if ($remove < 0) {
|
||||
$remove = 0;
|
||||
}
|
||||
|
||||
array_splice($content, 0, $remove);
|
||||
|
||||
if (isset($_GET['origin']) && $_GET['origin'] == 'whoisonline') {
|
||||
//the caller
|
||||
$content[0] = get_lang('CallSent').'<br />'.$content[0];
|
||||
}
|
||||
|
||||
$history = '<div id="content-chat">';
|
||||
foreach ($content as $this_line) {
|
||||
$history .= $this_line;
|
||||
}
|
||||
$history .= '</div>';
|
||||
|
||||
if ($isMaster || $GLOBALS['is_session_general_coach']) {
|
||||
$history .= '
|
||||
<div id="clear-chat">
|
||||
<button type="button" id="chat-reset" class="btn btn-danger btn-sm">
|
||||
'.get_lang('ClearList').'
|
||||
</button>
|
||||
</div>
|
||||
';
|
||||
}
|
||||
|
||||
return $history;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of users connected in chat.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function countUsersOnline()
|
||||
{
|
||||
$date = new DateTime(api_get_utc_datetime(), new DateTimeZone('UTC'));
|
||||
$date->modify('-5 seconds');
|
||||
|
||||
if ($this->groupId) {
|
||||
$extraCondition = 'AND ccc.toGroupId = '.intval($this->groupId);
|
||||
} else {
|
||||
$extraCondition = 'AND ccc.sessionId = '.intval($this->sessionId);
|
||||
}
|
||||
|
||||
$number = Database::getManager()
|
||||
->createQuery("
|
||||
SELECT COUNT(ccc.userId) FROM ChamiloCourseBundle:CChatConnected ccc
|
||||
WHERE ccc.lastConnection > :date AND ccc.cId = :course $extraCondition
|
||||
")
|
||||
->setParameters([
|
||||
'date' => $date,
|
||||
'course' => $this->courseId,
|
||||
])
|
||||
->getSingleScalarResult();
|
||||
|
||||
return (int) $number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the users online data.
|
||||
*
|
||||
* @throws \Doctrine\ORM\ORMException
|
||||
* @throws \Doctrine\ORM\OptimisticLockException
|
||||
* @throws \Doctrine\ORM\TransactionRequiredException
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function listUsersOnline()
|
||||
{
|
||||
$subscriptions = $this->getUsersSubscriptions();
|
||||
$usersInfo = [];
|
||||
|
||||
if ($this->groupId) {
|
||||
/** @var User $groupUser */
|
||||
foreach ($subscriptions as $groupUser) {
|
||||
$usersInfo[] = $this->formatUser(
|
||||
$groupUser,
|
||||
$groupUser->getStatus()
|
||||
);
|
||||
}
|
||||
} else {
|
||||
/** @var CourseRelUser|SessionRelCourseRelUser $subscription */
|
||||
foreach ($subscriptions as $subscription) {
|
||||
$user = $subscription->getUser();
|
||||
$usersInfo[] = $this->formatUser(
|
||||
$user,
|
||||
$this->sessionId ? $user->getStatus() : $subscription->getStatus()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $usersInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the user data to return it in the user list.
|
||||
*
|
||||
* @param int $status
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function formatUser(User $user, $status)
|
||||
{
|
||||
return [
|
||||
'id' => $user->getId(),
|
||||
'firstname' => $user->getFirstname(),
|
||||
'lastname' => $user->getLastname(),
|
||||
'status' => $status,
|
||||
'image_url' => UserManager::getUserPicture($user->getId(), USER_IMAGE_SIZE_MEDIUM),
|
||||
'profile_url' => api_get_path(WEB_CODE_PATH).'social/profile.php?u='.$user->getId(),
|
||||
'complete_name' => UserManager::formatUserFullName($user),
|
||||
'username' => $user->getUsername(),
|
||||
'email' => $user->getEmail(),
|
||||
'isConnected' => $this->userIsConnected($user->getId()),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the users subscriptions (SessionRelCourseRelUser array or CourseRelUser array) for chat.
|
||||
*
|
||||
* @throws \Doctrine\ORM\ORMException
|
||||
* @throws \Doctrine\ORM\OptimisticLockException
|
||||
* @throws \Doctrine\ORM\TransactionRequiredException
|
||||
*
|
||||
* @return \Doctrine\Common\Collections\ArrayCollection
|
||||
*/
|
||||
private function getUsersSubscriptions()
|
||||
{
|
||||
$em = Database::getManager();
|
||||
|
||||
if ($this->groupId) {
|
||||
$students = $em
|
||||
->createQuery(
|
||||
'SELECT u FROM ChamiloUserBundle:User u
|
||||
INNER JOIN ChamiloCourseBundle:CGroupRelUser gru
|
||||
WITH u.id = gru.userId AND gru.cId = :course
|
||||
WHERE u.id != :user AND gru.groupId = :group
|
||||
AND u.active = true'
|
||||
)
|
||||
->setParameters(['course' => $this->courseId, 'user' => $this->userId, 'group' => $this->groupId])
|
||||
->getResult();
|
||||
$tutors = $em
|
||||
->createQuery(
|
||||
'SELECT u FROM ChamiloUserBundle:User u
|
||||
INNER JOIN ChamiloCourseBundle:CGroupRelTutor grt
|
||||
WITH u.id = grt.userId AND grt.cId = :course
|
||||
WHERE u.id != :user AND grt.groupId = :group
|
||||
AND u.active = true'
|
||||
)
|
||||
->setParameters(['course' => $this->courseId, 'user' => $this->userId, 'group' => $this->groupId])
|
||||
->getResult();
|
||||
|
||||
return array_merge($tutors, $students);
|
||||
}
|
||||
|
||||
/** @var Course $course */
|
||||
$course = $em->find('ChamiloCoreBundle:Course', $this->courseId);
|
||||
|
||||
if ($this->sessionId) {
|
||||
/** @var Session $session */
|
||||
$session = $em->find('ChamiloCoreBundle:Session', $this->sessionId);
|
||||
$criteria = Criteria::create()->where(Criteria::expr()->eq('course', $course));
|
||||
$userIsCoach = api_is_course_session_coach($this->userId, $course->getId(), $session->getId());
|
||||
|
||||
if (api_get_configuration_value('course_chat_restrict_to_coach')) {
|
||||
if ($userIsCoach) {
|
||||
$criteria->andWhere(
|
||||
Criteria::expr()->eq('status', Session::STUDENT)
|
||||
);
|
||||
} else {
|
||||
$criteria->andWhere(
|
||||
Criteria::expr()->eq('status', Session::COACH)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$criteria->orderBy(['status' => Criteria::DESC]);
|
||||
|
||||
return $session
|
||||
->getUserCourseSubscriptions()
|
||||
->matching($criteria)
|
||||
->filter(function (SessionRelCourseRelUser $sessionRelCourseRelUser) {
|
||||
return $sessionRelCourseRelUser->getUser()->isActive();
|
||||
});
|
||||
}
|
||||
|
||||
return $course
|
||||
->getUsers()
|
||||
->filter(function (CourseRelUser $courseRelUser) {
|
||||
return $courseRelUser->getUser()->isActive();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a user is connected in course chat.
|
||||
*
|
||||
* @param int $userId
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function userIsConnected($userId)
|
||||
{
|
||||
$date = new DateTime(api_get_utc_datetime(), new DateTimeZone('UTC'));
|
||||
$date->modify('-5 seconds');
|
||||
|
||||
if ($this->groupId) {
|
||||
$extraCondition = 'AND ccc.toGroupId = '.intval($this->groupId);
|
||||
} else {
|
||||
$extraCondition = 'AND ccc.sessionId = '.intval($this->sessionId);
|
||||
}
|
||||
|
||||
$number = Database::getManager()
|
||||
->createQuery("
|
||||
SELECT COUNT(ccc.userId) FROM ChamiloCourseBundle:CChatConnected ccc
|
||||
WHERE ccc.lastConnection > :date AND ccc.cId = :course AND ccc.userId = :user $extraCondition
|
||||
")
|
||||
->setParameters([
|
||||
'date' => $date,
|
||||
'course' => $this->courseId,
|
||||
'user' => $userId,
|
||||
])
|
||||
->getSingleScalarResult();
|
||||
|
||||
return (int) $number;
|
||||
}
|
||||
}
|
||||
2465
main/inc/lib/CoursesAndSessionsCatalog.class.php
Normal file
2465
main/inc/lib/CoursesAndSessionsCatalog.class.php
Normal file
File diff suppressed because it is too large
Load Diff
263
main/inc/lib/ExerciseCategoryManager.php
Normal file
263
main/inc/lib/ExerciseCategoryManager.php
Normal file
@@ -0,0 +1,263 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use Chamilo\CourseBundle\Entity\CExerciseCategory;
|
||||
|
||||
/**
|
||||
* Class ExtraFieldValue
|
||||
* Declaration for the ExtraFieldValue class, managing the values in extra
|
||||
* fields for any data type.
|
||||
*/
|
||||
class ExerciseCategoryManager extends Model
|
||||
{
|
||||
public $type = '';
|
||||
public $columns = [
|
||||
'id',
|
||||
'name',
|
||||
'c_id',
|
||||
'description',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
];
|
||||
|
||||
/**
|
||||
* Formats the necessary elements for the given datatype.
|
||||
*
|
||||
* @assert (-1) === false
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->is_course_model = true;
|
||||
$this->table = Database::get_course_table('exercise_category');
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of values stored in the table (all fields together)
|
||||
* for this type of resource.
|
||||
*
|
||||
* @param int $courseId
|
||||
*
|
||||
* @return int Number of rows in the table
|
||||
*/
|
||||
public function getCourseCount($courseId)
|
||||
{
|
||||
$em = Database::getManager();
|
||||
$query = $em->getRepository('ChamiloCourseBundle:CExerciseCategory')->createQueryBuilder('e');
|
||||
$query->select('count(e.id)');
|
||||
$query->where('e.cId = :cId');
|
||||
$query->setParameter('cId', $courseId);
|
||||
|
||||
return $query->getQuery()->getSingleScalarResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $courseId
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getCategories($courseId)
|
||||
{
|
||||
$em = Database::getManager();
|
||||
$query = $em->getRepository('ChamiloCourseBundle:CExerciseCategory')->createQueryBuilder('e');
|
||||
$query->where('e.cId = :cId');
|
||||
$query->setParameter('cId', $courseId);
|
||||
$query->orderBy('e.position');
|
||||
|
||||
return $query->getQuery()->getResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $courseId
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getCategoriesForSelect($courseId)
|
||||
{
|
||||
$categories = $this->getCategories($courseId);
|
||||
$options = [];
|
||||
|
||||
if (!empty($categories)) {
|
||||
/** @var CExerciseCategory $category */
|
||||
foreach ($categories as $category) {
|
||||
$options[$category->getId()] = $category->getName();
|
||||
}
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
*/
|
||||
public function delete($id)
|
||||
{
|
||||
$em = Database::getManager();
|
||||
$repo = Database::getManager()->getRepository('ChamiloCourseBundle:CExerciseCategory');
|
||||
$category = $repo->find($id);
|
||||
if ($category) {
|
||||
$em->remove($category);
|
||||
$em->flush();
|
||||
|
||||
$courseId = api_get_course_int_id();
|
||||
$table = Database::get_course_table(TABLE_QUIZ_TEST);
|
||||
$id = (int) $id;
|
||||
|
||||
$sql = "UPDATE $table SET exercise_category_id = 0
|
||||
WHERE c_id = $courseId AND exercise_category_id = $id";
|
||||
Database::query($sql);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save values in the *_field_values table.
|
||||
*
|
||||
* @param array $params Structured array with the values to save
|
||||
* @param bool $showQuery Whether to show the insert query (passed to the parent save() method)
|
||||
*/
|
||||
public function save($params, $showQuery = false)
|
||||
{
|
||||
$em = Database::getManager();
|
||||
$category = new CExerciseCategory();
|
||||
$category
|
||||
->setName($params['name'])
|
||||
->setCId(api_get_course_int_id())
|
||||
->setDescription($params['name'])
|
||||
;
|
||||
/*
|
||||
// Update position
|
||||
$query = $em->getRepository('ChamiloCourseBundle:CExerciseCategory')->createQueryBuilder('e');
|
||||
$query
|
||||
->where('e.cId = :cId')
|
||||
->setParameter('cId', $courseId)
|
||||
->setMaxResults(1)
|
||||
->orderBy('e.position', 'DESC');
|
||||
$last = $query->getQuery()->getOneOrNullResult();
|
||||
$position = 0;
|
||||
if (!empty($last)) {
|
||||
$position = $last->getPosition() + 1;
|
||||
}
|
||||
$category->setPosition($position);
|
||||
*/
|
||||
$em->persist($category);
|
||||
$em->flush();
|
||||
|
||||
return $category;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $token
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getJqgridActionLinks($token)
|
||||
{
|
||||
//With this function we can add actions to the jgrid (edit, delete, etc)
|
||||
$editIcon = Display::return_icon('edit.png', get_lang('Edit'), '', ICON_SIZE_SMALL);
|
||||
$deleteIcon = Display::return_icon('delete.png', get_lang('Delete'), '', ICON_SIZE_SMALL);
|
||||
$confirmMessage = addslashes(
|
||||
api_htmlentities(get_lang('ConfirmYourChoice'), ENT_QUOTES)
|
||||
);
|
||||
|
||||
$courseParams = api_get_cidreq();
|
||||
|
||||
$editButton = <<<JAVASCRIPT
|
||||
<a href="?action=edit&{$courseParams}&id=' + options.rowId + '" class="btn btn-link btn-xs">\
|
||||
$editIcon\
|
||||
</a>
|
||||
JAVASCRIPT;
|
||||
$deleteButton = <<<JAVASCRIPT
|
||||
<a \
|
||||
onclick="if (!confirm(\'$confirmMessage\')) {return false;}" \
|
||||
href="?sec_token=$token&{$courseParams}&id=' + options.rowId + '&action=delete" \
|
||||
class="btn btn-link btn-xs">\
|
||||
$deleteIcon\
|
||||
</a>
|
||||
JAVASCRIPT;
|
||||
|
||||
return "function action_formatter(cellvalue, options, rowObject) {
|
||||
return '$editButton $deleteButton';
|
||||
}";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @param string $action
|
||||
*
|
||||
* @return FormValidator
|
||||
*/
|
||||
public function return_form($url, $action)
|
||||
{
|
||||
$form = new FormValidator('category', 'post', $url);
|
||||
$id = isset($_GET['id']) ? (int) $_GET['id'] : null;
|
||||
$form->addElement('hidden', 'id', $id);
|
||||
|
||||
// Setting the form elements
|
||||
$header = get_lang('Add');
|
||||
$defaults = [];
|
||||
|
||||
if ($action === 'edit') {
|
||||
$header = get_lang('Modify');
|
||||
// Setting the defaults
|
||||
$defaults = $this->get($id, false);
|
||||
}
|
||||
|
||||
$form->addElement('header', $header);
|
||||
|
||||
$form->addText(
|
||||
'name',
|
||||
get_lang('Name')
|
||||
);
|
||||
|
||||
$form->addHtmlEditor('description', get_lang('Description'));
|
||||
|
||||
if ($action === 'edit') {
|
||||
$form->addButtonUpdate(get_lang('Modify'));
|
||||
} else {
|
||||
$form->addButtonCreate(get_lang('Add'));
|
||||
}
|
||||
|
||||
/*if (!empty($defaults['created_at'])) {
|
||||
$defaults['created_at'] = api_convert_and_format_date($defaults['created_at']);
|
||||
}
|
||||
if (!empty($defaults['updated_at'])) {
|
||||
$defaults['updated_at'] = api_convert_and_format_date($defaults['updated_at']);
|
||||
}*/
|
||||
$form->setDefaults($defaults);
|
||||
|
||||
// Setting the rules
|
||||
$form->addRule('name', get_lang('ThisFieldIsRequired'), 'required');
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function display()
|
||||
{
|
||||
// action links
|
||||
$content = '<div class="actions">';
|
||||
$content .= '<a href="'.api_get_path(WEB_CODE_PATH).'exercise/exercise.php?'.api_get_cidreq().'">';
|
||||
$content .= Display::return_icon(
|
||||
'back.png',
|
||||
get_lang('BackTo').' '.get_lang('PlatformAdmin'),
|
||||
'',
|
||||
ICON_SIZE_MEDIUM
|
||||
);
|
||||
$content .= '</a>';
|
||||
$content .= '<a href="'.api_get_self().'?action=add&'.api_get_cidreq().'">';
|
||||
$content .= Display::return_icon(
|
||||
'add.png',
|
||||
get_lang('Add'),
|
||||
'',
|
||||
ICON_SIZE_MEDIUM
|
||||
);
|
||||
$content .= '</a>';
|
||||
$content .= '</div>';
|
||||
$content .= Display::grid_html('categories');
|
||||
|
||||
return $content;
|
||||
}
|
||||
}
|
||||
231
main/inc/lib/GamificationUtils.php
Normal file
231
main/inc/lib/GamificationUtils.php
Normal file
@@ -0,0 +1,231 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* GamificationUtils class
|
||||
* Functions to manage the gamification mode.
|
||||
*
|
||||
* @author Angel Fernando Quiroz Campos <angel.quiroz@beeznest.com>
|
||||
*/
|
||||
class GamificationUtils
|
||||
{
|
||||
/**
|
||||
* Get the calculated points on session with gamification mode.
|
||||
*
|
||||
* @param int $userId The user ID
|
||||
* @param int $userStatus The user Status
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public static function getTotalUserPoints($userId, $userStatus)
|
||||
{
|
||||
$points = 0;
|
||||
|
||||
$sessions = SessionManager::getSessionsFollowedByUser(
|
||||
$userId,
|
||||
$userStatus
|
||||
);
|
||||
|
||||
if (empty($sessions)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
foreach ($sessions as $session) {
|
||||
$points += self::getSessionPoints($session['id'], $userId);
|
||||
}
|
||||
|
||||
return round($points / count($sessions), 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the achieved points for an user in a session.
|
||||
*
|
||||
* @param int $sessionId The session ID
|
||||
* @param int $userId The user ID
|
||||
*
|
||||
* @return int The count of points
|
||||
*/
|
||||
public static function getSessionPoints($sessionId, $userId)
|
||||
{
|
||||
$totalPoints = 0;
|
||||
$courses = SessionManager::get_course_list_by_session_id($sessionId);
|
||||
|
||||
if (empty($courses)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
foreach ($courses as $course) {
|
||||
$learnPathListObject = new LearnpathList(
|
||||
$userId,
|
||||
api_get_course_info($course['code']),
|
||||
$sessionId
|
||||
);
|
||||
$learnPaths = $learnPathListObject->get_flat_list();
|
||||
|
||||
if (empty($learnPaths)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$score = 0;
|
||||
|
||||
foreach ($learnPaths as $learnPathId => $learnPathInfo) {
|
||||
if (empty($learnPathInfo['seriousgame_mode'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$learnPath = new learnpath(
|
||||
$course['code'],
|
||||
$learnPathId,
|
||||
$userId
|
||||
);
|
||||
$score += $learnPath->getCalculateScore($sessionId);
|
||||
}
|
||||
$totalPoints += round($score / count($learnPaths), 2);
|
||||
}
|
||||
|
||||
return round($totalPoints / count($courses), 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the calculated progress for an user in a session.
|
||||
*
|
||||
* @param int $sessionId The session ID
|
||||
* @param int $userId The user ID
|
||||
*
|
||||
* @return float The progress
|
||||
*/
|
||||
public static function getSessionProgress($sessionId, $userId)
|
||||
{
|
||||
$courses = SessionManager::get_course_list_by_session_id($sessionId);
|
||||
$progress = 0;
|
||||
|
||||
if (empty($courses)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
foreach ($courses as $course) {
|
||||
$courseProgress = Tracking::get_avg_student_progress(
|
||||
$userId,
|
||||
$course['code'],
|
||||
[],
|
||||
$sessionId,
|
||||
false,
|
||||
true
|
||||
);
|
||||
|
||||
if (false === $courseProgress) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$progress += $courseProgress;
|
||||
}
|
||||
|
||||
return round($progress / count($courses), 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of stars achieved for an user in a session.
|
||||
*
|
||||
* @param int $sessionId The session ID
|
||||
* @param int $userId The user ID
|
||||
*
|
||||
* @return int The number of stars
|
||||
*/
|
||||
public static function getSessionStars($sessionId, $userId)
|
||||
{
|
||||
$totalStars = 0;
|
||||
$courses = SessionManager::get_course_list_by_session_id($sessionId);
|
||||
|
||||
if (empty($courses)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
foreach ($courses as $course) {
|
||||
$learnPathListObject = new LearnpathList(
|
||||
$userId,
|
||||
api_get_course_info($course['code']),
|
||||
$sessionId
|
||||
);
|
||||
$learnPaths = $learnPathListObject->get_flat_list();
|
||||
|
||||
if (empty($learnPaths)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$stars = 0;
|
||||
|
||||
foreach ($learnPaths as $learnPathId => $learnPathInfo) {
|
||||
if (empty($learnPathInfo['seriousgame_mode'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$learnPath = new learnpath(
|
||||
$course['code'],
|
||||
$learnPathId,
|
||||
$userId
|
||||
);
|
||||
|
||||
$stars += $learnPath->getCalculateStars($sessionId);
|
||||
}
|
||||
|
||||
$totalStars += round($stars / count($learnPaths));
|
||||
}
|
||||
|
||||
return round($totalStars / count($courses));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the stars on sessions with gamification mode.
|
||||
*
|
||||
* @param int $userId The user ID
|
||||
* @param int $userStatus The user Status
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function getTotalUserStars($userId, $userStatus)
|
||||
{
|
||||
$stars = 0;
|
||||
$sessions = SessionManager::getSessionsFollowedByUser(
|
||||
$userId,
|
||||
$userStatus
|
||||
);
|
||||
|
||||
if (empty($sessions)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
foreach ($sessions as $session) {
|
||||
$stars += self::getSessionStars($session['id'], $userId);
|
||||
}
|
||||
|
||||
return round($stars / count($sessions));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the total progress on sessions with gamification mode.
|
||||
*
|
||||
* @param int $userId The user ID
|
||||
* @param int $userStatus The user Status
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public static function getTotalUserProgress($userId, $userStatus)
|
||||
{
|
||||
$progress = 0;
|
||||
|
||||
$sessions = SessionManager::getSessionsFollowedByUser(
|
||||
$userId,
|
||||
$userStatus
|
||||
);
|
||||
|
||||
if (empty($sessions)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
foreach ($sessions as $session) {
|
||||
$progress += self::getSessionProgress($session['id'], $userId);
|
||||
}
|
||||
|
||||
return round($progress / count($sessions), 2);
|
||||
}
|
||||
}
|
||||
237
main/inc/lib/MailTemplateManager.php
Normal file
237
main/inc/lib/MailTemplateManager.php
Normal file
@@ -0,0 +1,237 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use Symfony\Component\Finder\Finder;
|
||||
|
||||
/**
|
||||
* Class MailTemplateManager.
|
||||
*/
|
||||
class MailTemplateManager extends Model
|
||||
{
|
||||
public $columns = [
|
||||
'id',
|
||||
'name',
|
||||
'template',
|
||||
'type',
|
||||
'system',
|
||||
'url_id',
|
||||
'default_template',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
'author_id',
|
||||
];
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->table = 'mail_template';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function get_count()
|
||||
{
|
||||
$row = Database::select(
|
||||
'count(*) as count',
|
||||
$this->table,
|
||||
['where' => ['url_id = ? ' => api_get_current_access_url_id()]],
|
||||
'first'
|
||||
);
|
||||
|
||||
return $row['count'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the title + grid.
|
||||
*
|
||||
* @return string html code
|
||||
*/
|
||||
public function display()
|
||||
{
|
||||
// Action links
|
||||
$html = '<div class="actions" style="margin-bottom:20px">';
|
||||
$html .= '<a href="'.api_get_path(WEB_CODE_PATH).'admin">'.
|
||||
Display::return_icon(
|
||||
'back.png',
|
||||
get_lang('Back'),
|
||||
'',
|
||||
'32'
|
||||
)
|
||||
.'</a>';
|
||||
$html .= '<a href="'.api_get_self().'?action=add">'.
|
||||
Display::return_icon(
|
||||
'add.png',
|
||||
get_lang('Add'),
|
||||
'',
|
||||
'32'
|
||||
).'</a>';
|
||||
$html .= '</div>';
|
||||
$html .= Display::grid_html('mail_template');
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Form validator Obj.
|
||||
*
|
||||
* @param string $url
|
||||
* @param string $action
|
||||
*
|
||||
* @return FormValidator
|
||||
*/
|
||||
public function returnForm($url, $action = 'add')
|
||||
{
|
||||
$form = new FormValidator('template', 'post', $url);
|
||||
// Setting the form elements
|
||||
$header = get_lang('Add');
|
||||
if ($action === 'edit') {
|
||||
$header = get_lang('Modify');
|
||||
}
|
||||
$id = isset($_GET['id']) ? (int) $_GET['id'] : '';
|
||||
|
||||
$form->addElement('header', '', $header);
|
||||
$form->addElement('hidden', 'id', $id);
|
||||
$form->addElement(
|
||||
'text',
|
||||
'name',
|
||||
get_lang('Name'),
|
||||
['size' => '70', 'id' => 'name']
|
||||
);
|
||||
|
||||
/*$form->addHtmlEditor(
|
||||
'email_template',
|
||||
get_lang('Template'),
|
||||
false,
|
||||
false,
|
||||
[
|
||||
'ToolbarSet' => 'Careers',
|
||||
'Width' => '100%',
|
||||
'Height' => '250',
|
||||
]
|
||||
);*/
|
||||
$form->addTextarea(
|
||||
'email_template',
|
||||
get_lang('Template')
|
||||
);
|
||||
|
||||
$finder = new Finder();
|
||||
$files = $finder
|
||||
->files()
|
||||
->in(api_get_path(SYS_CODE_PATH).'template/default/mail')
|
||||
->sort(
|
||||
function ($a, $b) {
|
||||
return strcmp($a->getRealpath(), $b->getRealpath());
|
||||
}
|
||||
);
|
||||
|
||||
$options = [];
|
||||
/** @var SplFileInfo $file */
|
||||
foreach ($files as $file) {
|
||||
$options[$file->getFilename()] = $file->getFilename();
|
||||
}
|
||||
|
||||
$form->addSelect(
|
||||
'type',
|
||||
get_lang('Type'),
|
||||
$options
|
||||
);
|
||||
|
||||
$defaults = $this->get($id);
|
||||
|
||||
if ($action === 'edit') {
|
||||
$form->addLabel(get_lang('CreatedAt'), Display::dateToStringAgoAndLongDate($defaults['created_at']));
|
||||
$form->addLabel(get_lang('UpdatedAt'), Display::dateToStringAgoAndLongDate($defaults['updated_at']));
|
||||
$form->addButtonSave(get_lang('Modify'), 'submit');
|
||||
} else {
|
||||
$form->addButtonCreate(get_lang('Add'), 'submit');
|
||||
}
|
||||
|
||||
// Setting the defaults
|
||||
if (!empty($defaults)) {
|
||||
$defaults['email_template'] = $defaults['template'];
|
||||
}
|
||||
$form->setDefaults($defaults);
|
||||
|
||||
// Setting the rules
|
||||
$form->addRule('name', get_lang('ThisFieldIsRequired'), 'required');
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function setDefault($id)
|
||||
{
|
||||
$template = $this->get($id);
|
||||
if (empty($template)) {
|
||||
return false;
|
||||
}
|
||||
$type = $template['type'];
|
||||
$urlId = api_get_current_access_url_id();
|
||||
$sql = "UPDATE {$this->table} SET default_template = 0
|
||||
WHERE type = '$type' AND url_id = $urlId";
|
||||
Database::query($sql);
|
||||
|
||||
$sql = "UPDATE {$this->table} SET default_template = 1
|
||||
WHERE id = $id";
|
||||
Database::query($sql);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $templateId
|
||||
* @param array $userInfo
|
||||
*
|
||||
* @return string|false
|
||||
*/
|
||||
public function parseTemplate($templateId, $userInfo)
|
||||
{
|
||||
$templateInfo = $this->get($templateId);
|
||||
if (!empty($templateInfo)) {
|
||||
$emailTemplate = nl2br($templateInfo['template']);
|
||||
|
||||
$keys = array_keys($userInfo);
|
||||
foreach ($keys as $key) {
|
||||
$emailTemplate = str_replace("{{user.$key}}", $userInfo[$key], $emailTemplate);
|
||||
}
|
||||
$template = new Template();
|
||||
$template->twig->setLoader(new \Twig_Loader_String());
|
||||
$emailBody = $template->twig->render($emailTemplate);
|
||||
|
||||
return $emailBody;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a custom mail template by the name of the template it replaces.
|
||||
*
|
||||
* @param string $templateType Name of the template file it replaces
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTemplateByType($templateType)
|
||||
{
|
||||
if (empty($templateType)) {
|
||||
return '';
|
||||
}
|
||||
$result = Database::select(
|
||||
'template',
|
||||
$this->table,
|
||||
['where' => ['type = ? ' => $templateType, ' AND url_id = ? ' => api_get_current_access_url_id()]],
|
||||
'first'
|
||||
);
|
||||
if (empty($result)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $result['template'];
|
||||
}
|
||||
}
|
||||
2880
main/inc/lib/MoodleImport.php
Normal file
2880
main/inc/lib/MoodleImport.php
Normal file
File diff suppressed because it is too large
Load Diff
101
main/inc/lib/MyStudents.php
Normal file
101
main/inc/lib/MyStudents.php
Normal file
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
class MyStudents
|
||||
{
|
||||
public static function userCareersTable(int $studentId): string
|
||||
{
|
||||
if (!api_get_configuration_value('allow_career_users')) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$careers = UserManager::getUserCareers($studentId);
|
||||
|
||||
if (empty($careers)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$title = Display::page_subheader(get_lang('Careers'), null, 'h3', ['class' => 'section-title']);
|
||||
|
||||
return $title.self::getCareersTable($careers, $studentId);
|
||||
}
|
||||
|
||||
public static function getCareersTable(array $careers, int $studentId): string
|
||||
{
|
||||
if (empty($careers)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$webCodePath = api_get_path(WEB_CODE_PATH);
|
||||
$iconDiagram = Display::return_icon('multiplicate_survey.png', get_lang('Diagram'));
|
||||
$careerModel = new Career();
|
||||
|
||||
$headers = [
|
||||
get_lang('Career'),
|
||||
get_lang('Diagram'),
|
||||
];
|
||||
|
||||
$data = array_map(
|
||||
function (array $careerInfo) use ($careerModel, $webCodePath, $iconDiagram, $studentId) {
|
||||
$careerId = $careerInfo['id'];
|
||||
if (api_get_configuration_value('use_career_external_id_as_identifier_in_diagrams')) {
|
||||
$careerId = $careerModel->getCareerIdFromInternalToExternal($careerId);
|
||||
}
|
||||
|
||||
$url = $webCodePath.'user/career_diagram.php?career_id='.$careerId.'&user_id='.$studentId;
|
||||
|
||||
return [
|
||||
$careerInfo['name'],
|
||||
Display::url($iconDiagram, $url),
|
||||
];
|
||||
},
|
||||
$careers
|
||||
);
|
||||
|
||||
$table = new HTML_Table(['class' => 'table table-hover table-striped data_table']);
|
||||
$table->setHeaders($headers);
|
||||
$table->setData($data);
|
||||
|
||||
return $table->toHtml();
|
||||
}
|
||||
|
||||
public static function getBlockForSkills(int $studentId, int $courseId, int $sessionId): string
|
||||
{
|
||||
$allowAll = api_get_configuration_value('allow_teacher_access_student_skills');
|
||||
|
||||
if ($allowAll) {
|
||||
return Tracking::displayUserSkills($studentId, 0, 0, true);
|
||||
}
|
||||
|
||||
// Default behaviour - Show all skills depending the course and session id
|
||||
return Tracking::displayUserSkills($studentId, $courseId, $sessionId);
|
||||
}
|
||||
|
||||
public static function getBlockForClasses($studentId): ?string
|
||||
{
|
||||
$userGroupManager = new UserGroup();
|
||||
$userGroups = $userGroupManager->getNameListByUser(
|
||||
$studentId,
|
||||
UserGroup::NORMAL_CLASS
|
||||
);
|
||||
|
||||
if (empty($userGroups)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$headers = [get_lang('Classes')];
|
||||
$data = array_map(
|
||||
function ($class) {
|
||||
return [$class];
|
||||
},
|
||||
$userGroups
|
||||
);
|
||||
|
||||
$table = new HTML_Table(['class' => 'table table-hover table-striped data_table']);
|
||||
$table->setHeaders($headers);
|
||||
$table->setData($data);
|
||||
|
||||
return $table->toHtml();
|
||||
}
|
||||
}
|
||||
452
main/inc/lib/NotificationEvent.php
Normal file
452
main/inc/lib/NotificationEvent.php
Normal file
@@ -0,0 +1,452 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
class NotificationEvent extends Model
|
||||
{
|
||||
public const ACCOUNT_EXPIRATION = 1;
|
||||
public const JUSTIFICATION_EXPIRATION = 2;
|
||||
public const GLOBAL_NOTIFICATION = 3;
|
||||
public const SPECIFIC_USER = 4;
|
||||
|
||||
public $table;
|
||||
public $columns = [
|
||||
'id',
|
||||
'title',
|
||||
'content',
|
||||
'link',
|
||||
'persistent',
|
||||
'day_diff',
|
||||
'event_type',
|
||||
'event_id',
|
||||
];
|
||||
public $extraFieldName;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->table = 'notification_event';
|
||||
$this->extraFieldName = 'notification_event';
|
||||
}
|
||||
|
||||
public function eventTypeToString($eventTypeId)
|
||||
{
|
||||
$list = $this->getEventsForSelect(false);
|
||||
|
||||
return $list[$eventTypeId];
|
||||
}
|
||||
|
||||
public function getEventsForSelect($onlyEnabled = true): array
|
||||
{
|
||||
$eventTypes = [
|
||||
self::ACCOUNT_EXPIRATION => get_lang('AccountExpiration'),
|
||||
self::GLOBAL_NOTIFICATION => get_lang('Global'),
|
||||
self::SPECIFIC_USER => get_lang('SpecificUsers'),
|
||||
];
|
||||
|
||||
if (!$onlyEnabled || api_get_plugin_setting('justification', 'tool_enable') === 'true') {
|
||||
$eventTypes[self::JUSTIFICATION_EXPIRATION] = get_lang('JustificationExpiration');
|
||||
}
|
||||
|
||||
return $eventTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getForm(FormValidator $form, $data = []): FormValidator
|
||||
{
|
||||
$options = $this->getEventsForSelect();
|
||||
$form->addSelect('event_type', get_lang('EventType'), $options);
|
||||
$form->freeze('event_type');
|
||||
|
||||
$eventType = $data['event_type'];
|
||||
switch ($eventType) {
|
||||
case self::JUSTIFICATION_EXPIRATION:
|
||||
$list = [];
|
||||
if (api_get_plugin_setting('justification', 'tool_enable') === 'true'
|
||||
&& $list = Justification::create()->getList()
|
||||
) {
|
||||
$list = array_column($list, 'name', 'id');
|
||||
}
|
||||
$form->addSelect('event_id', get_lang('JustificationType'), $list);
|
||||
$form->freeze('event_id');
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
$form->addText('title', get_lang('Title'));
|
||||
$form->addTextarea('content', get_lang('Content'));
|
||||
$form->addText('link', get_lang('Link'), false);
|
||||
$form->addCheckBox('persistent', get_lang('Persistent'));
|
||||
$form->addNumeric('day_diff', get_lang('DaysDifference'), false);
|
||||
|
||||
switch ($eventType) {
|
||||
case self::SPECIFIC_USER:
|
||||
$form->addSelectAjax(
|
||||
'users',
|
||||
get_lang('Users'),
|
||||
$data['users'] ?? [],
|
||||
[
|
||||
'url' => api_get_path(WEB_AJAX_PATH).'user_manager.ajax.php?a=get_user_like',
|
||||
'multiple' => 'multiple',
|
||||
]
|
||||
);
|
||||
//no break
|
||||
case self::GLOBAL_NOTIFICATION:
|
||||
$form->removeElement('day_diff');
|
||||
break;
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getAddForm(FormValidator $form): FormValidator
|
||||
{
|
||||
$options = $this->getEventsForSelect();
|
||||
$eventType = $form->getSubmitValue('event_type');
|
||||
|
||||
$form->addSelect(
|
||||
'event_type',
|
||||
get_lang('EventType'),
|
||||
$options,
|
||||
['placeholder' => get_lang('SelectAnOption'), 'onchange' => 'document.add.submit()']
|
||||
);
|
||||
|
||||
if (!empty($eventType)) {
|
||||
$form->freeze('event_type');
|
||||
$form->addText('title', get_lang('Title'));
|
||||
$form->addTextarea('content', get_lang('Content'));
|
||||
$form->addText('link', get_lang('Link'), false);
|
||||
$form->addCheckBox('persistent', get_lang('Persistent'));
|
||||
$form->addNumeric('day_diff', get_lang('DaysDifference'), false);
|
||||
|
||||
switch ($eventType) {
|
||||
case self::JUSTIFICATION_EXPIRATION:
|
||||
$list = [];
|
||||
if (api_get_plugin_setting('justification', 'tool_enable') === 'true'
|
||||
&& $list = Justification::create()->getList()
|
||||
) {
|
||||
$list = array_column($list, 'name', 'id');
|
||||
}
|
||||
$form->addSelect('event_id', get_lang('JustificationType'), $list);
|
||||
break;
|
||||
case self::SPECIFIC_USER:
|
||||
$form->addSelectAjax(
|
||||
'users',
|
||||
get_lang('Users'),
|
||||
[],
|
||||
[
|
||||
'url' => api_get_path(WEB_AJAX_PATH).'user_manager.ajax.php?a=get_user_like',
|
||||
'multiple' => 'multiple',
|
||||
]
|
||||
);
|
||||
//no break
|
||||
case self::GLOBAL_NOTIFICATION:
|
||||
$form->removeElement('day_diff');
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
$form->addButtonSave(get_lang('Save'));
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
public function getUserExtraData($userId)
|
||||
{
|
||||
$data = UserManager::get_extra_user_data_by_field($userId, $this->extraFieldName);
|
||||
|
||||
return $data['notification_event'] ?? '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getNotificationsByUser(int $userId): array
|
||||
{
|
||||
$userInfo = api_get_user_info($userId);
|
||||
$events = $this->get_all();
|
||||
$extraFieldData = $this->getUserExtraData($userId);
|
||||
|
||||
$notifications = [];
|
||||
foreach ($events as $event) {
|
||||
$days = (int) $event['day_diff'];
|
||||
$checkIsRead = $event['persistent'] == 0;
|
||||
$eventItemId = $event['event_id'];
|
||||
|
||||
switch ($event['event_type']) {
|
||||
case self::ACCOUNT_EXPIRATION:
|
||||
if (empty($userInfo['expiration_date'])) {
|
||||
break;
|
||||
}
|
||||
|
||||
$id = 'id_'.self::ACCOUNT_EXPIRATION.'_event_'.$event['id'].'_'.$userInfo['id'];
|
||||
|
||||
$read = false;
|
||||
if ($checkIsRead) {
|
||||
$read = $this->isRead($id, $extraFieldData);
|
||||
}
|
||||
|
||||
$showNotification = $this->showNotification($userInfo['expiration_date'], $days);
|
||||
if ($showNotification && $read === false) {
|
||||
$notifications[] = [
|
||||
'id' => $id,
|
||||
'title' => $event['title'],
|
||||
'content' => $event['content'],
|
||||
'event_text' => get_lang('ExpirationDate').': '.api_get_local_time($userInfo['expiration_date']),
|
||||
'link' => $event['link'],
|
||||
'persistent' => $event['persistent'],
|
||||
];
|
||||
}
|
||||
break;
|
||||
case self::JUSTIFICATION_EXPIRATION:
|
||||
if (api_get_plugin_setting('justification', 'tool_enable') !== 'true') {
|
||||
break;
|
||||
}
|
||||
|
||||
$plugin = Justification::create();
|
||||
$userJustificationList = $plugin->getUserJustificationList($userId);
|
||||
|
||||
foreach ($userJustificationList as $userJustification) {
|
||||
if (empty($userJustification['date_validity'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($eventItemId != $userJustification['justification_document_id']) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$showNotification = $this->showNotification($userJustification['date_validity'], $days);
|
||||
|
||||
$id = 'id_'.self::JUSTIFICATION_EXPIRATION.'_event_'.$event['id'].'_'.$userJustification['id'];
|
||||
|
||||
$fieldData = $plugin->getJustification($userJustification['justification_document_id']);
|
||||
|
||||
$read = false;
|
||||
if ($checkIsRead) {
|
||||
$read = $this->isRead($id, $extraFieldData);
|
||||
}
|
||||
|
||||
$eventText = $plugin->get_lang('Justification').': '.$fieldData['name'].' <br />';
|
||||
$eventText .= $plugin->get_lang('JustificationDate').': '.$userJustification['date_validity'];
|
||||
|
||||
$url = $event['link'];
|
||||
if (empty($url)) {
|
||||
$url = api_get_path(WEB_CODE_PATH).'auth/justification.php#'.$fieldData['code'];
|
||||
}
|
||||
|
||||
if ($showNotification && $read === false) {
|
||||
$notifications[] = [
|
||||
'id' => $id,
|
||||
'title' => $event['title'],
|
||||
'content' => $event['content'],
|
||||
'event_text' => $eventText,
|
||||
'link' => $url,
|
||||
'persistent' => $event['persistent'],
|
||||
];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case self::SPECIFIC_USER:
|
||||
$assignedUsers = self::getAssignedUsers($event['id']);
|
||||
$assignedUserIdList = array_keys($assignedUsers);
|
||||
|
||||
if (!in_array($userId, $assignedUserIdList)) {
|
||||
break;
|
||||
}
|
||||
//no break
|
||||
case self::GLOBAL_NOTIFICATION:
|
||||
$id = "id_{$event['event_type']}_event_{$event['id']}_$userId";
|
||||
|
||||
$wasRead = $checkIsRead && $this->isRead($id, $extraFieldData);
|
||||
|
||||
if (!$wasRead) {
|
||||
$notifications[] = [
|
||||
'id' => $id,
|
||||
'title' => $event['title'],
|
||||
'content' => $event['content'],
|
||||
'event_text' => null,
|
||||
'link' => $event['link'],
|
||||
'persistent' => $event['persistent'],
|
||||
];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $notifications;
|
||||
}
|
||||
|
||||
public function isRead($id, $extraData): bool
|
||||
{
|
||||
$userId = api_get_user_id();
|
||||
|
||||
if (empty($extraData)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$data = $this->getUserExtraData($userId);
|
||||
if (empty($data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$data = json_decode($data);
|
||||
|
||||
if (in_array($id, $data)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function markAsRead($id): bool
|
||||
{
|
||||
if (empty($id)) {
|
||||
return false;
|
||||
}
|
||||
$userId = api_get_user_id();
|
||||
$data = $this->getUserExtraData($userId);
|
||||
if (!empty($data)) {
|
||||
$data = json_decode($data);
|
||||
} else {
|
||||
$data = [];
|
||||
}
|
||||
$data[] = $id;
|
||||
$data = json_encode($data);
|
||||
|
||||
UserManager::update_extra_field_value($userId, $this->extraFieldName, $data);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function showNotification($date, $dayDiff): bool
|
||||
{
|
||||
$today = api_get_utc_datetime();
|
||||
$expiration = api_get_utc_datetime($date, false, true);
|
||||
$interval = new DateInterval('P'.$dayDiff.'D');
|
||||
$diff = $expiration->sub($interval);
|
||||
|
||||
if ($diff->format('Y-m-d H:i:s') < $today) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function install()
|
||||
{
|
||||
$sql = "CREATE TABLE IF NOT EXISTS notification_event (
|
||||
id INT unsigned NOT NULL auto_increment PRIMARY KEY,
|
||||
title VARCHAR(255),
|
||||
content TEXT,
|
||||
link TEXT,
|
||||
persistent INT,
|
||||
day_diff INT,
|
||||
event_type VARCHAR(255)
|
||||
)";
|
||||
Database::query($sql);
|
||||
}
|
||||
|
||||
public function save($params, $show_query = false)
|
||||
{
|
||||
$userIdList = [];
|
||||
|
||||
if (isset($params['users'])) {
|
||||
$userIdList = $params['users'];
|
||||
unset($params['users']);
|
||||
}
|
||||
|
||||
/** @var int|bool $saved */
|
||||
$saved = parent::save($params, $show_query);
|
||||
|
||||
if (false !== $saved && !empty($userIdList)) {
|
||||
self::assignUserIdList($saved, $userIdList);
|
||||
}
|
||||
|
||||
return $saved;
|
||||
}
|
||||
|
||||
public function update($params, $showQuery = false): bool
|
||||
{
|
||||
$userIdList = [];
|
||||
|
||||
if (isset($params['users'])) {
|
||||
$userIdList = $params['users'];
|
||||
unset($params['users']);
|
||||
}
|
||||
|
||||
$updated = parent::update($params, $showQuery);
|
||||
|
||||
self::deleteAssignedUsers($params['id']);
|
||||
self::assignUserIdList($params['id'], $userIdList);
|
||||
|
||||
return $updated;
|
||||
}
|
||||
|
||||
public function get($id)
|
||||
{
|
||||
$props = parent::get($id);
|
||||
$props['users'] = self::getAssignedUsers($id);
|
||||
|
||||
return $props;
|
||||
}
|
||||
|
||||
public static function assignUserIdList(int $eventId, array $userIdList)
|
||||
{
|
||||
foreach ($userIdList as $userId) {
|
||||
Database::insert(
|
||||
'notification_event_rel_user',
|
||||
[
|
||||
'event_id' => $eventId,
|
||||
'user_id' => (int) $userId,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public static function getAssignedUsers(int $eventId): array
|
||||
{
|
||||
$tblUser = Database::get_main_table(TABLE_MAIN_USER);
|
||||
|
||||
$result = Database::select(
|
||||
'u.id, u.username, u.firstname, u.lastname',
|
||||
"notification_event_rel_user neru INNER JOIN $tblUser u ON neru.user_id = u.id",
|
||||
['where' => ['neru.event_id = ?' => $eventId]]
|
||||
);
|
||||
|
||||
$userList = [];
|
||||
|
||||
foreach ($result as $userInfo) {
|
||||
$userList[$userInfo['id']] = api_get_person_name(
|
||||
$userInfo['firstname'],
|
||||
$userInfo['lastname'],
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
$userInfo['username']
|
||||
);
|
||||
}
|
||||
|
||||
return $userList;
|
||||
}
|
||||
|
||||
public static function deleteAssignedUsers(int $eventId)
|
||||
{
|
||||
Database::delete(
|
||||
'notification_event_rel_user',
|
||||
['event_id = ?' => $eventId]
|
||||
);
|
||||
}
|
||||
}
|
||||
4495
main/inc/lib/PortfolioController.php
Normal file
4495
main/inc/lib/PortfolioController.php
Normal file
File diff suppressed because it is too large
Load Diff
102
main/inc/lib/PortfolioNotifier.php
Normal file
102
main/inc/lib/PortfolioNotifier.php
Normal file
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use Chamilo\CoreBundle\Entity\Course as CourseEntity;
|
||||
use Chamilo\CoreBundle\Entity\PortfolioComment;
|
||||
use Chamilo\CoreBundle\Entity\Session as SessionEntity;
|
||||
|
||||
class PortfolioNotifier
|
||||
{
|
||||
public static function notifyTeachersAndAuthor(PortfolioComment $comment)
|
||||
{
|
||||
$item = $comment->getItem();
|
||||
$course = $item->getCourse();
|
||||
$session = $item->getSession();
|
||||
|
||||
$messageSubject = sprintf(
|
||||
get_lang('PortfolioAlertNewCommentSubject'),
|
||||
$item->getTitle(true)
|
||||
);
|
||||
$userIdListToSend = [];
|
||||
$userIdListToSend[] = $comment->getItem()->getUser()->getId();
|
||||
|
||||
$cidreq = api_get_cidreq_params(
|
||||
$course ? $course->getCode() : '',
|
||||
$session ? $session->getId() : 0
|
||||
);
|
||||
$commentUrl = api_get_path(WEB_CODE_PATH).'portfolio/index.php?'
|
||||
.($course ? $cidreq.'&' : '')
|
||||
.http_build_query(['action' => 'view', 'id' => $item->getId()])."#comment-{$comment->getId()}";
|
||||
|
||||
if ($course) {
|
||||
$courseInfo = api_get_course_info($course->getCode());
|
||||
|
||||
if (1 !== (int) api_get_course_setting('email_alert_teachers_student_new_comment', $courseInfo)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$courseTitle = self::getCourseTitle($course, $session);
|
||||
$userIdListToSend = array_merge(
|
||||
$userIdListToSend,
|
||||
self::getTeacherList($course, $session)
|
||||
);
|
||||
|
||||
$messageContent = sprintf(
|
||||
get_lang('CoursePortfolioAlertNewCommentContent'),
|
||||
$item->getTitle(),
|
||||
$courseTitle,
|
||||
$commentUrl
|
||||
);
|
||||
} else {
|
||||
$messageContent = sprintf(
|
||||
get_lang('PortfolioAlertNewCommentContent'),
|
||||
$item->getTitle(),
|
||||
$commentUrl
|
||||
);
|
||||
}
|
||||
|
||||
$messageContent .= '<br><br><figure>'
|
||||
.'<blockquote>'.$comment->getExcerpt().'</blockquote>'
|
||||
.'<figcaption>'.$comment->getAuthor()->getCompleteName().'</figcaption>'
|
||||
.'</figure>';
|
||||
|
||||
foreach ($userIdListToSend as $userIdToSend) {
|
||||
MessageManager::send_message_simple(
|
||||
$userIdToSend,
|
||||
$messageSubject,
|
||||
$messageContent,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
[],
|
||||
false
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private static function getCourseTitle(CourseEntity $course, ?SessionEntity $session = null): string
|
||||
{
|
||||
if ($session) {
|
||||
return "{$course->getTitle()} ({$session->getName()})";
|
||||
}
|
||||
|
||||
return $course->getTitle();
|
||||
}
|
||||
|
||||
private static function getTeacherList(CourseEntity $course, ?SessionEntity $session = null): array
|
||||
{
|
||||
if ($session) {
|
||||
$teachers = SessionManager::getCoachesByCourseSession(
|
||||
$session->getId(),
|
||||
$course->getId()
|
||||
);
|
||||
|
||||
return array_values($teachers);
|
||||
}
|
||||
|
||||
$teachers = CourseManager::get_teacher_list_from_course_code($course->getCode());
|
||||
|
||||
return array_keys($teachers);
|
||||
}
|
||||
}
|
||||
612
main/inc/lib/ScheduledAnnouncement.php
Normal file
612
main/inc/lib/ScheduledAnnouncement.php
Normal file
@@ -0,0 +1,612 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Class ScheduledAnnouncement
|
||||
* Requires DB change:.
|
||||
*
|
||||
* CREATE TABLE scheduled_announcements (id INT AUTO_INCREMENT NOT NULL, subject VARCHAR(255) NOT NULL, message LONGTEXT NOT NULL, date DATETIME DEFAULT NULL, sent TINYINT(1) NOT NULL, session_id INT NOT NULL, c_id INT DEFAULT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;
|
||||
*
|
||||
* Config setting:
|
||||
* $_configuration['allow_scheduled_announcements'] = true;
|
||||
*
|
||||
* Setup linux cron file:
|
||||
* main/cron/scheduled_announcement.php
|
||||
*
|
||||
* Requires:
|
||||
* composer update
|
||||
*/
|
||||
class ScheduledAnnouncement extends Model
|
||||
{
|
||||
public $table;
|
||||
public $columns = ['id', 'subject', 'message', 'date', 'sent', 'session_id'];
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->table = 'scheduled_announcements';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $where_conditions
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_all($where_conditions = [])
|
||||
{
|
||||
return Database::select(
|
||||
'*',
|
||||
$this->table,
|
||||
['where' => $where_conditions, 'order' => 'subject ASC']
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function get_count()
|
||||
{
|
||||
$row = Database::select(
|
||||
'count(*) as count',
|
||||
$this->table,
|
||||
[],
|
||||
'first'
|
||||
);
|
||||
|
||||
return $row['count'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the title + grid.
|
||||
*
|
||||
* @param int $sessionId
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getGrid($sessionId)
|
||||
{
|
||||
// action links
|
||||
$action = '<div class="actions" style="margin-bottom:20px">';
|
||||
$action .= Display::url(
|
||||
Display::return_icon('back.png', get_lang('Back'), '', ICON_SIZE_MEDIUM),
|
||||
api_get_path(WEB_CODE_PATH).'session/resume_session.php?id_session='.$sessionId
|
||||
);
|
||||
|
||||
$action .= '<a href="'.api_get_self().'?action=add&session_id='.$sessionId.'">'.
|
||||
Display::return_icon('add.png', get_lang('Add'), '', ICON_SIZE_MEDIUM).'</a>';
|
||||
$action .= '<a href="scheduled_announcement.php?action=run&session_id='.$sessionId.'">'.
|
||||
Display::return_icon('tuning.png', get_lang('SendManuallyPendingAnnouncements'), '', ICON_SIZE_MEDIUM).
|
||||
'</a>';
|
||||
|
||||
$action .= '</div>';
|
||||
|
||||
$html = $action;
|
||||
$html .= '<div id="session-table" class="table-responsive">';
|
||||
$html .= Display::grid_html('programmed');
|
||||
$html .= '</div>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Form validator Obj.
|
||||
*
|
||||
* @param int $id
|
||||
* @param string $url
|
||||
* @param string $action add, edit
|
||||
* @param array $sessionInfo
|
||||
*
|
||||
* @return FormValidator form validator obj
|
||||
*/
|
||||
public function returnSimpleForm($id, $url, $action, $sessionInfo = [])
|
||||
{
|
||||
$form = new FormValidator(
|
||||
'announcement',
|
||||
'post',
|
||||
$url
|
||||
);
|
||||
|
||||
$form->addHidden('session_id', $sessionInfo['id']);
|
||||
$form->addDateTimePicker('date', get_lang('Date'));
|
||||
|
||||
$useBaseProgress = api_get_configuration_value('scheduled_announcements_use_base_progress');
|
||||
if ($useBaseProgress) {
|
||||
$extraFieldValue = new ExtraFieldValue('scheduled_announcement');
|
||||
$baseProgress = $extraFieldValue->get_values_by_handler_and_field_variable(
|
||||
$id,
|
||||
'use_base_progress'
|
||||
);
|
||||
$form->addNumeric('progress',
|
||||
get_lang('Progress'),
|
||||
[
|
||||
'step' => 1,
|
||||
'min' => 1,
|
||||
'max' => 100,
|
||||
'value' => $baseProgress['value'],
|
||||
],
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
$form->addText('subject', get_lang('Subject'));
|
||||
$form->addHtmlEditor('message', get_lang('Message'));
|
||||
|
||||
$extraField = new ExtraField('scheduled_announcement');
|
||||
$extra = $extraField->addElements($form, $id);
|
||||
$js = $extra['jquery_ready_content'];
|
||||
$form->addHtml("<script> $(function() { $js }); </script> ");
|
||||
|
||||
$this->setTagsInForm($form);
|
||||
|
||||
$form->addCheckBox('sent', null, get_lang('MessageSent'));
|
||||
|
||||
if ('edit' === $action) {
|
||||
$form->addButtonUpdate(get_lang('Modify'));
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Form validator Obj.
|
||||
*
|
||||
* @todo the form should be auto generated
|
||||
*
|
||||
* @param string $url
|
||||
* @param string $action add, edit
|
||||
* @param array
|
||||
*
|
||||
* @return FormValidator form validator obj
|
||||
*/
|
||||
public function returnForm($url, $action, $sessionInfo = [])
|
||||
{
|
||||
// Setting the form elements
|
||||
$header = get_lang('Add');
|
||||
|
||||
if ('edit' === $action) {
|
||||
$header = get_lang('Modify');
|
||||
}
|
||||
|
||||
$form = new FormValidator(
|
||||
'announcement',
|
||||
'post',
|
||||
$url
|
||||
);
|
||||
|
||||
$form->addHeader($header);
|
||||
if ('add' === $action) {
|
||||
$form->addHtml(
|
||||
Display::return_message(
|
||||
nl2br(get_lang('ScheduleAnnouncementDescription')),
|
||||
'normal',
|
||||
false
|
||||
)
|
||||
);
|
||||
}
|
||||
$form->addHidden('session_id', $sessionInfo['id']);
|
||||
|
||||
$useBaseDate = false;
|
||||
$startDate = $sessionInfo['access_start_date'];
|
||||
$endDate = $sessionInfo['access_end_date'];
|
||||
|
||||
if (!empty($startDate) || !empty($endDate)) {
|
||||
$useBaseDate = true;
|
||||
}
|
||||
|
||||
$typeOptions = [
|
||||
'specific_date' => get_lang('SpecificDate'),
|
||||
];
|
||||
|
||||
if ($useBaseDate) {
|
||||
$typeOptions['base_date'] = get_lang('BaseDate');
|
||||
}
|
||||
|
||||
$useBaseProgress = api_get_configuration_value('scheduled_announcements_use_base_progress');
|
||||
if ($useBaseProgress) {
|
||||
$typeOptions['base_progress'] = get_lang('Progress');
|
||||
}
|
||||
|
||||
$form->addSelect(
|
||||
'type',
|
||||
get_lang('Type'),
|
||||
$typeOptions,
|
||||
[
|
||||
'onchange' => "javascript:
|
||||
if (this.options[this.selectedIndex].value == 'base_date') {
|
||||
document.getElementById('options').style.display = 'block';
|
||||
document.getElementById('specific_date').style.display = 'none';
|
||||
document.getElementById('base_progress').style.display = 'none';
|
||||
} else if (this.options[this.selectedIndex].value == 'specific_date') {
|
||||
document.getElementById('options').style.display = 'none';
|
||||
document.getElementById('specific_date').style.display = 'block';
|
||||
document.getElementById('base_progress').style.display = 'none';
|
||||
} else {
|
||||
document.getElementById('options').style.display = 'block';
|
||||
document.getElementById('specific_date').style.display = 'none';
|
||||
document.getElementById('base_progress').style.display = 'block';
|
||||
}
|
||||
", ]
|
||||
);
|
||||
|
||||
$form->addHtml('<div id="specific_date">');
|
||||
$form->addDateTimePicker('date', get_lang('Date'));
|
||||
$form->addHtml('</div>');
|
||||
|
||||
$form->addHtml('<div id="base_progress" style="display:none">');
|
||||
$form->addNumeric('progress',
|
||||
get_lang('Progress'),
|
||||
[
|
||||
'step' => 1,
|
||||
'min' => 1,
|
||||
'max' => 100,
|
||||
'value' => 100,
|
||||
],
|
||||
true
|
||||
);
|
||||
$form->addHtml('</div>');
|
||||
|
||||
$form->addHtml('<div id="options" style="display:none">');
|
||||
|
||||
$startDate = $sessionInfo['access_start_date'];
|
||||
$endDate = $sessionInfo['access_end_date'];
|
||||
|
||||
$form->addText(
|
||||
'days',
|
||||
get_lang('Days'),
|
||||
false
|
||||
);
|
||||
|
||||
$form->addSelect(
|
||||
'moment_type',
|
||||
get_lang('AfterOrBefore'),
|
||||
[
|
||||
'after' => get_lang('After'),
|
||||
'before' => get_lang('Before'),
|
||||
]
|
||||
);
|
||||
|
||||
if (!empty($startDate)) {
|
||||
$options['start_date'] = get_lang('StartDate').' - '.$startDate;
|
||||
}
|
||||
|
||||
if (!empty($endDate)) {
|
||||
$options['end_date'] = get_lang('EndDate').' - '.$endDate;
|
||||
}
|
||||
if (!empty($options)) {
|
||||
$form->addSelect('base_date', get_lang('BaseDate'), $options);
|
||||
}
|
||||
|
||||
$form->addHtml('</div>');
|
||||
$form->addText('subject', get_lang('Subject'));
|
||||
$form->addHtmlEditor('message', get_lang('Message'));
|
||||
|
||||
$extraField = new ExtraField('scheduled_announcement');
|
||||
$extra = $extraField->addElements($form);
|
||||
$js = $extra['jquery_ready_content'];
|
||||
$form->addHtml("<script> $(function() { $js }); </script> ");
|
||||
|
||||
$this->setTagsInForm($form);
|
||||
|
||||
if ('edit' === $action) {
|
||||
$form->addButtonUpdate(get_lang('Modify'));
|
||||
} else {
|
||||
$form->addButtonCreate(get_lang('Add'));
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAttachmentToString($id)
|
||||
{
|
||||
$file = $this->getAttachment($id);
|
||||
if (!empty($file) && !empty($file['value'])) {
|
||||
$url = api_get_path(WEB_UPLOAD_PATH).$file['value'];
|
||||
|
||||
return get_lang('Attachment').': '.Display::url(basename($file['value']), $url, ['target' => '_blank']);
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAttachment($id)
|
||||
{
|
||||
$extraFieldValue = new ExtraFieldValue('scheduled_announcement');
|
||||
$attachment = $extraFieldValue->get_values_by_handler_and_field_variable($id, 'attachment');
|
||||
|
||||
return $attachment;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $urlId
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function sendPendingMessages($urlId = 0)
|
||||
{
|
||||
if (!$this->allowed()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$messagesSent = 0;
|
||||
$now = api_get_utc_datetime();
|
||||
$result = $this->get_all();
|
||||
$extraFieldValue = new ExtraFieldValue('scheduled_announcement');
|
||||
|
||||
// get user extra fields list (only visible to self and filter-able)
|
||||
$extraField = new ExtraField('user');
|
||||
$extraFields = $extraField->get_all(['filter = ? AND visible_to_self = ?' => [1, 1]]);
|
||||
|
||||
foreach ($result as $result) {
|
||||
if (empty($result['sent'])) {
|
||||
if (!empty($result['date']) && $result['date'] < $now) {
|
||||
$sessionId = $result['session_id'];
|
||||
$sessionInfo = api_get_session_info($sessionId);
|
||||
if (empty($sessionInfo)) {
|
||||
continue;
|
||||
}
|
||||
$users = SessionManager::get_users_by_session(
|
||||
$sessionId,
|
||||
0,
|
||||
false,
|
||||
$urlId
|
||||
);
|
||||
|
||||
$coachId = $sessionInfo['id_coach'];
|
||||
|
||||
if (empty($users) || empty($coachId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$coachList = [];
|
||||
if ($users) {
|
||||
$sendToCoaches = $extraFieldValue->get_values_by_handler_and_field_variable(
|
||||
$result['id'],
|
||||
'send_to_coaches'
|
||||
);
|
||||
$courseList = SessionManager::getCoursesInSession($sessionId);
|
||||
if (!empty($sendToCoaches) && !empty($sendToCoaches['value']) && 1 == $sendToCoaches['value']) {
|
||||
foreach ($courseList as $courseItemId) {
|
||||
$coaches = SessionManager::getCoachesByCourseSession(
|
||||
$sessionId,
|
||||
$courseItemId
|
||||
);
|
||||
$coachList = array_merge($coachList, $coaches);
|
||||
}
|
||||
$coachList = array_unique($coachList);
|
||||
}
|
||||
|
||||
$useBaseProgress = api_get_configuration_value('scheduled_announcements_use_base_progress');
|
||||
if ($useBaseProgress) {
|
||||
$baseProgress = $extraFieldValue->get_values_by_handler_and_field_variable(
|
||||
$result['id'],
|
||||
'use_base_progress'
|
||||
);
|
||||
if (empty($baseProgress) || empty($baseProgress['value']) || $baseProgress['value'] < 1) {
|
||||
$this->update(['id' => $result['id'], 'sent' => 1]);
|
||||
}
|
||||
} else {
|
||||
$this->update(['id' => $result['id'], 'sent' => 1]);
|
||||
}
|
||||
|
||||
$attachments = $this->getAttachmentToString($result['id']);
|
||||
$subject = $result['subject'];
|
||||
|
||||
$courseInfo = [];
|
||||
if (!empty($courseList)) {
|
||||
$courseId = current($courseList);
|
||||
$courseInfo = api_get_course_info_by_id($courseId);
|
||||
}
|
||||
|
||||
$message = '';
|
||||
foreach ($users as $user) {
|
||||
// Take original message
|
||||
$message = $result['message'];
|
||||
$userInfo = api_get_user_info($user['user_id']);
|
||||
$userPicture = UserManager::getUserPicture($user['user_id'], USER_IMAGE_SIZE_ORIGINAL);
|
||||
|
||||
$progress = '';
|
||||
if (!empty($sessionInfo) && !empty($courseInfo)) {
|
||||
$progress = Tracking::get_avg_student_progress(
|
||||
$user['user_id'],
|
||||
$courseInfo['code'],
|
||||
[],
|
||||
$sessionId
|
||||
);
|
||||
}
|
||||
|
||||
if ($useBaseProgress) {
|
||||
$baseProgress = $extraFieldValue->get_values_by_handler_and_field_variable(
|
||||
$result['id'],
|
||||
'use_base_progress'
|
||||
);
|
||||
if (!empty($baseProgress) && !empty($baseProgress['value']) && $baseProgress['value'] >= 1) {
|
||||
if ((is_numeric($progress) && $progress > $baseProgress['value']) || !is_numeric($progress)) {
|
||||
continue;
|
||||
} else {
|
||||
$comment = json_decode($baseProgress['comment'], true);
|
||||
if ($comment !== null && is_array($comment)) {
|
||||
if (isset($comment['sended']) && is_array($comment['sended'])) {
|
||||
$userFound = false;
|
||||
foreach ($comment['sended'] as $item) {
|
||||
if (isset($item['user']) && $item['user'] === $user['user_id']) {
|
||||
$userFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($userFound) {
|
||||
continue;
|
||||
} else {
|
||||
$comment['sended'][] = ['user' => $user['user_id'], 'send_date' => time(), 'progress_user' => $progress, 'progress_mark' => $baseProgress['value']];
|
||||
$newExtraFieldParams = $baseProgress;
|
||||
$newExtraFieldParams['comment'] = json_encode($comment);
|
||||
$extraFieldValue->save($newExtraFieldParams);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$comment['sended'][] = ['user' => $user['user_id'], 'send_date' => time(), 'progress_user' => $progress, 'progress_mark' => $baseProgress['value']];
|
||||
$newExtraFieldParams = $baseProgress;
|
||||
$newExtraFieldParams['comment'] = json_encode($comment);
|
||||
$extraFieldValue->save($newExtraFieldParams);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (is_numeric($progress)) {
|
||||
$progress = $progress.'%';
|
||||
} else {
|
||||
$progress = '0%';
|
||||
}
|
||||
|
||||
$startTime = api_get_local_time(
|
||||
$sessionInfo['access_start_date'],
|
||||
null,
|
||||
null,
|
||||
true
|
||||
);
|
||||
$endTime = api_get_local_time(
|
||||
$sessionInfo['access_end_date'],
|
||||
null,
|
||||
null,
|
||||
true
|
||||
);
|
||||
|
||||
$generalCoach = '';
|
||||
$generalCoachEmail = '';
|
||||
if (!empty($coachId)) {
|
||||
$coachInfo = api_get_user_info($coachId);
|
||||
if (!empty($coachInfo)) {
|
||||
$generalCoach = $coachInfo['complete_name'];
|
||||
$generalCoachEmail = $coachInfo['email'];
|
||||
}
|
||||
}
|
||||
|
||||
$tags = [
|
||||
'((session_name))' => $sessionInfo['name'],
|
||||
'((session_start_date))' => $startTime,
|
||||
'((general_coach))' => $generalCoach,
|
||||
'((general_coach_email))' => $generalCoachEmail,
|
||||
'((session_end_date))' => $endTime,
|
||||
'((user_username))' => $userInfo['username'],
|
||||
'((user_complete_name))' => $userInfo['complete_name'],
|
||||
'((user_firstname))' => $userInfo['firstname'],
|
||||
'((user_lastname))' => $userInfo['lastname'],
|
||||
'((user_first_name))' => $userInfo['firstname'],
|
||||
'((user_last_name))' => $userInfo['lastname'],
|
||||
'((user_official_code))' => $userInfo['official_code'],
|
||||
'((user_picture))' => $userPicture,
|
||||
'((lp_progress))' => $progress,
|
||||
];
|
||||
|
||||
if (!empty($extraFields)) {
|
||||
$efv = new ExtraFieldValue('user');
|
||||
|
||||
foreach ($extraFields as $extraField) {
|
||||
$valueExtra = $efv->get_values_by_handler_and_field_variable(
|
||||
$user['user_id'],
|
||||
$extraField['variable'],
|
||||
true
|
||||
);
|
||||
$tags['(('.strtolower($extraField['variable']).'))'] = $valueExtra['value'];
|
||||
}
|
||||
}
|
||||
|
||||
$message = str_replace(array_keys($tags), $tags, $message);
|
||||
$message .= $attachments;
|
||||
|
||||
MessageManager::send_message_simple(
|
||||
$userInfo['user_id'],
|
||||
$subject,
|
||||
$message,
|
||||
$coachId
|
||||
);
|
||||
}
|
||||
|
||||
$message = get_lang('YouAreReceivingACopyBecauseYouAreACourseCoach').'<br /><br />'.$message;
|
||||
|
||||
foreach ($coachList as $courseCoachId) {
|
||||
MessageManager::send_message_simple(
|
||||
$courseCoachId,
|
||||
get_lang('YouAreReceivingACopyBecauseYouAreACourseCoach').' '.$subject,
|
||||
$message,
|
||||
$coachId
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$messagesSent++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $messagesSent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getTags()
|
||||
{
|
||||
$tags = [
|
||||
'((session_name))',
|
||||
'((session_start_date))',
|
||||
'((session_end_date))',
|
||||
'((general_coach))',
|
||||
'((general_coach_email))',
|
||||
'((user_username))',
|
||||
'((user_complete_name))',
|
||||
'((user_first_name))',
|
||||
'((user_last_name))',
|
||||
'((user_picture))',
|
||||
'((lp_progress))',
|
||||
'((user_official_code))',
|
||||
];
|
||||
// get user extra fields list (only visible to self and filter-able)
|
||||
$extraField = new ExtraField('user');
|
||||
$extraFields = $extraField->get_all(['filter = ? AND visible_to_self = ?' => [1, 1]]);
|
||||
if (!empty($extraFields)) {
|
||||
foreach ($extraFields as $extraField) {
|
||||
$tags[] = '(('.strtolower($extraField['variable']).'))';
|
||||
}
|
||||
}
|
||||
|
||||
return $tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function allowed()
|
||||
{
|
||||
return api_get_configuration_value('allow_scheduled_announcements');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FormValidator $form
|
||||
*/
|
||||
private function setTagsInForm(&$form)
|
||||
{
|
||||
$form->addLabel(
|
||||
get_lang('Tags'),
|
||||
Display::return_message(
|
||||
implode('<br />', $this->getTags()),
|
||||
'normal',
|
||||
false
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
143
main/inc/lib/SmsPlugin.php
Normal file
143
main/inc/lib/SmsPlugin.php
Normal file
@@ -0,0 +1,143 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Class SmsPlugin.
|
||||
*
|
||||
* @author Julio Montoya
|
||||
*/
|
||||
class SmsPlugin extends Plugin
|
||||
{
|
||||
public const WELCOME_LOGIN_PASSWORD = 0;
|
||||
public const NEW_FILE_SHARED_COURSE_BY = 1;
|
||||
public const ACCOUNT_APPROVED_CONNECT = 2;
|
||||
public const NEW_COURSE_BEEN_CREATED = 3;
|
||||
public const NEW_USER_SUBSCRIBED_COURSE = 4;
|
||||
public const NEW_COURSE_SUGGESTED_TEACHER = 5;
|
||||
public const COURSE_OPENING_REQUEST_CODE_REGISTERED = 6;
|
||||
public const COURSE_OPENING_REQUEST_CODE_APPROVED = 7;
|
||||
public const COURSE_OPENING_REQUEST_CODE_REJECTED = 8;
|
||||
public const COURSE_OPENING_REQUEST_CODE = 9;
|
||||
public const BEEN_SUBSCRIBED_COURSE = 10;
|
||||
public const ASSIGNMENT_BEEN_CREATED_COURSE = 11;
|
||||
public const ACCOUNT_CREATED_UPDATED_LOGIN_PASSWORD = 12;
|
||||
public const PASSWORD_UPDATED_LOGIN_PASSWORD = 13;
|
||||
public const REQUESTED_PASSWORD_CHANGE = 14;
|
||||
public const RECEIVED_NEW_PERSONAL_MESSAGES = 15;
|
||||
public const NEW_USER_PENDING_APPROVAL = 16;
|
||||
public const POSTED_FORUM_COURSE = 17;
|
||||
public const CHECK_EMAIL_CONNECT_MORE_INFO = 18;
|
||||
public const STUDENT_ANSWERED_TEST = 19;
|
||||
public const STUDENT_ANSWERED_TEST_OPEN_QUESTION = 20;
|
||||
public const STUDENT_ANSWERED_TEST_VOICE_QUESTION = 21;
|
||||
public const ANSWER_OPEN_QUESTION_TEST_REVIEWED = 22;
|
||||
public const NEW_THREAD_STARTED_FORUM = 23;
|
||||
public const NEW_ANSWER_POSTED_FORUM = 24;
|
||||
public const NEW_SYSTEM_ANNOUNCEMENT_ADDED = 25;
|
||||
public const TEST_NEW_SYSTEM_ANNOUNCEMENT_ADDED = 26;
|
||||
public const SYSTEM_ANNOUNCEMENT_UPDATE = 27;
|
||||
public const TEST_SYSTEM_ANNOUNCEMENT_UPDATE = 28;
|
||||
public const USER_UPLOADED_ASSIGNMENT_COURSE_STUDENT_SUBMITS_PAPER = 29;
|
||||
public const USER_UPLOADED_ASSIGNMENT_CHECK_STUDENT_SUBMITS_PAPER = 30;
|
||||
public const USER_UPLOADED_ASSIGNMENT_COURSE = 31;
|
||||
public const USER_UPLOADED_ASSIGNMENT_CHECK = 32;
|
||||
public const SUBSCRIBED_SESSION = 33;
|
||||
public const SUBSCRIBED_SESSION_CSV = 34;
|
||||
public const USER_SUGGESTED_BE_FRIENDS = 35;
|
||||
public const USER_ANSWERED_INBOX_MESSAGE = 36;
|
||||
public const BEEN_INVITED_JOIN_GROUP = 37;
|
||||
public const MESSAGES_SENT_EDITED_GROUP_EDITED = 38;
|
||||
public const MESSAGES_SENT_EDITED_GROUP_ADDED = 39;
|
||||
public const BEEN_INVITED_COMPLETE_SURVEY_COURSE = 40;
|
||||
public const REMINDER_ASSIGNMENT_COURSE_DUE = 41;
|
||||
public const USER_DETAILS_MODIFIED = 42;
|
||||
public const CERTIFICATE_NOTIFICATION = 43;
|
||||
|
||||
public $isCoursePlugin = true;
|
||||
public $isMailPlugin = true;
|
||||
|
||||
/**
|
||||
* getSmsTypeOptions (returns all SMS types).
|
||||
*
|
||||
* @return array SMS types
|
||||
*/
|
||||
public function getSmsTypeOptions()
|
||||
{
|
||||
return [
|
||||
'MessageWelcomeXLoginXPasswordX',
|
||||
'MessageXNewFileSharedCourseXByX',
|
||||
'MessageXAccountApprovedConnectX',
|
||||
'MessageXNewCourseXBeenCreatedX',
|
||||
'MessageXNewUserXSubscribedCourseX',
|
||||
'MessageXNewCourseSuggestedTeacherX',
|
||||
'MessageXCourseOpeningRequestCodeXRegistered',
|
||||
'MessageXCourseOpeningRequestCourseCodeXApproved',
|
||||
'MessageXRequestOpenCourseCodeXReject',
|
||||
'MessageXCourseOpeningRequestCourseCodeX',
|
||||
'MessageXBeenSubscribedCourseX',
|
||||
'MessageXAssignmentBeenCreatedCourseX',
|
||||
'MessageXAccountCreatedUpdatedLoginXPasswordX',
|
||||
'MessageXPasswordUpdatedLoginXPasswordX',
|
||||
'MessageXRequestedPasswordChange',
|
||||
'MessageXReceivedNewPersonalMessages',
|
||||
'MessageXNewUserXPendingApproval',
|
||||
'MessageXXPostedForumXCourseX',
|
||||
'MessageXXXCheckEmailConnectMoreInfo',
|
||||
'MessageXXStudentXAnsweredTestX',
|
||||
'MessageXXStudentXAnsweredTestXOpenQuestion',
|
||||
'MessageXXStudentXAnsweredTestXVoiceQuestion',
|
||||
'MessageXXAnswerOpenQuestionTestXReviewed',
|
||||
'MessageXXNewThreadXStartedForumX',
|
||||
'MessageXXNewAnswerPostedXForumX',
|
||||
'MessageXXNewSystemAnnouncementAdded',
|
||||
'MessageXTestXNewSystemAnnouncementAdded',
|
||||
'MessageXXSystemAnnouncementUpdate',
|
||||
'MessageXTestXSystemAnnouncementUpdate',
|
||||
'MessageXUserXUploadedAssignmentXCourseXStudentSubmitsPaper',
|
||||
'MessageXUserXUploadedAssignmentXCheckXStudentSubmitsPaper',
|
||||
'MessageXUserXUploadedAssignmentXCourseX',
|
||||
'MessageXUserXUploadedAssignmentXCheckX',
|
||||
'MessageXSubscribedSessionX',
|
||||
'MessageXSubscribedSessionXCSV',
|
||||
'MessageXUserXSuggestedBeFriends',
|
||||
'MessageXUserXAnsweredInboxMessage',
|
||||
'MessageXBeenInvitedJoinGroupX',
|
||||
'MessageXMessagesSentEditedGroupXEdited',
|
||||
'MessageXMessagesSentEditedGroupXAdded',
|
||||
'MessageXBeenInvitedCompleteSurveyXCourseX',
|
||||
'MessageXReminderAssignmentXCourseXDue',
|
||||
'MessageXUserDetailsModified',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* install (installs the plugin).
|
||||
*/
|
||||
public function install()
|
||||
{
|
||||
$this->addMobilePhoneNumberField();
|
||||
}
|
||||
|
||||
/**
|
||||
* addMobilePhoneNumberField (adds a mobile phone number field if it is not
|
||||
* already created).
|
||||
*/
|
||||
private function addMobilePhoneNumberField()
|
||||
{
|
||||
$extraField = new ExtraField('user');
|
||||
$extraFieldInfo = $extraField->get_handler_field_info_by_field_variable('mobile_phone_number');
|
||||
|
||||
if (empty($extraFieldInfo)) {
|
||||
$extraField->save([
|
||||
'field_type' => 1,
|
||||
'variable' => 'mobile_phone_number',
|
||||
'display_text' => $this->get_lang('mobile_phone_number'),
|
||||
'default_value' => null,
|
||||
'field_order' => 2,
|
||||
'visible' => 1,
|
||||
'changeable' => 1,
|
||||
'filter' => null,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
46
main/inc/lib/SmsPluginLibraryInterface.php
Normal file
46
main/inc/lib/SmsPluginLibraryInterface.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Class SmsPluginLibraryInterface.
|
||||
*
|
||||
* @author Julio Montoya
|
||||
*/
|
||||
interface SmsPluginLibraryInterface
|
||||
{
|
||||
/**
|
||||
* getMobilePhoneNumberById (retrieves a user mobile phone number by user id).
|
||||
*
|
||||
* @param int $userId
|
||||
*
|
||||
* @return int User's mobile phone number
|
||||
*/
|
||||
public function getMobilePhoneNumberById($userId);
|
||||
|
||||
/**
|
||||
* @param array $additionalParameters
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function send($additionalParameters);
|
||||
|
||||
/**
|
||||
* @param array $additionalParameters
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getSms($additionalParameters);
|
||||
|
||||
/**
|
||||
* buildSms (builds an SMS from a template and data).
|
||||
*
|
||||
* @param object $plugin ClockworksmsPlugin object
|
||||
* @param object $tpl Template object
|
||||
* @param string $templateName Template file name
|
||||
* @param string $messageKey Text key from lang file
|
||||
* @param array $parameters Data to fill message variables (if any)
|
||||
*
|
||||
* @return object Template object with message property updated
|
||||
*/
|
||||
public function buildSms($plugin, $tpl, $templateName, $messageKey, $parameters = null);
|
||||
}
|
||||
89
main/inc/lib/SortableTableFromArray.php
Normal file
89
main/inc/lib/SortableTableFromArray.php
Normal file
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Sortable table which can be used for data available in an array.
|
||||
*/
|
||||
class SortableTableFromArray extends SortableTable
|
||||
{
|
||||
/**
|
||||
* The array containing all data for this table.
|
||||
*/
|
||||
public $table_data;
|
||||
public $handlePagination;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array $table_data
|
||||
* @param int $default_column
|
||||
* @param int $default_items_per_page
|
||||
* @param string $tableName
|
||||
* @param string $get_total_number_function
|
||||
* @param string $tableId
|
||||
*/
|
||||
public function __construct(
|
||||
$table_data,
|
||||
$default_column = 1,
|
||||
$default_items_per_page = 20,
|
||||
$tableName = 'tablename',
|
||||
$get_total_number_function = null,
|
||||
$tableId = ''
|
||||
) {
|
||||
parent::__construct(
|
||||
$tableName,
|
||||
$get_total_number_function,
|
||||
null,
|
||||
$default_column,
|
||||
$default_items_per_page,
|
||||
null,
|
||||
$tableId
|
||||
);
|
||||
$this->table_data = $table_data;
|
||||
$this->handlePagination = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get table data to show on current page.
|
||||
*
|
||||
* @see SortableTable#get_table_data
|
||||
*/
|
||||
public function get_table_data(
|
||||
$from = 1,
|
||||
$per_page = null,
|
||||
$column = null,
|
||||
$direction = null,
|
||||
$sort = true
|
||||
) {
|
||||
if ($sort) {
|
||||
$content = TableSort::sort_table(
|
||||
$this->table_data,
|
||||
$this->column,
|
||||
'ASC' === $this->direction ? SORT_ASC : SORT_DESC
|
||||
);
|
||||
} else {
|
||||
$content = $this->table_data;
|
||||
}
|
||||
|
||||
return array_slice($content, $from, $this->per_page);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get total number of items.
|
||||
*
|
||||
* @see SortableTable#get_total_number_of_items
|
||||
*/
|
||||
public function get_total_number_of_items()
|
||||
{
|
||||
if (isset($this->total_number_of_items) && !empty($this->total_number_of_items) && $this->total_number_of_items != -1) {
|
||||
return $this->total_number_of_items;
|
||||
} else {
|
||||
if (!empty($this->table_data)) {
|
||||
return count($this->table_data);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
118
main/inc/lib/SortableTableFromArrayConfig.php
Normal file
118
main/inc/lib/SortableTableFromArrayConfig.php
Normal file
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Sortable table which can be used for data available in an array.
|
||||
*
|
||||
* Is a variation of SortableTableFromArray because we add 2 new arrays $column_show and $column_order
|
||||
* $column_show is an array that lets us decide which are going to be the columns to show
|
||||
* $column_order is an array that lets us decide the ordering of the columns
|
||||
* i.e: $column_header=array('a','b','c','d','e'); $column_order=array(1,2,5,4,5);
|
||||
* These means that the 3th column (letter "c") will be sort like the order we use in the 5th column
|
||||
*/
|
||||
class SortableTableFromArrayConfig extends SortableTable
|
||||
{
|
||||
/**
|
||||
* The array containing the columns that will be show
|
||||
* i.e $column_show=array('1','0','0'); we will show only the 1st column.
|
||||
*/
|
||||
private $column_show;
|
||||
|
||||
/**
|
||||
* The array containing the real sort column
|
||||
* $column_order=array('1''4','3','4');
|
||||
* The 2nd column will be order like the 4th column.
|
||||
*/
|
||||
private $column_order;
|
||||
|
||||
private $doc_filter;
|
||||
private $handlePagination = true;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array $data All the information of the table
|
||||
* @param int $column Default column that will be used in the sort functions
|
||||
* @param int $itemsPerPage Number of items per pages that we are going to see
|
||||
* @param string $tableName Name of the table
|
||||
* @param array $columnShow An array with binary values: 1 = show column, 2 = don't show it
|
||||
* @param array $columnOrder An array of integers that let us decide how the columns are going to be sort
|
||||
* @param string $direction ASC/DESC
|
||||
* @param bool $docFilter special modification to fix the document name order
|
||||
*/
|
||||
public function __construct(
|
||||
$data,
|
||||
$column = 1,
|
||||
$itemsPerPage = 20,
|
||||
$tableName = 'tablename',
|
||||
$columnShow = [],
|
||||
$columnOrder = [],
|
||||
$direction = 'ASC',
|
||||
$docFilter = false
|
||||
) {
|
||||
$this->column_show = $columnShow;
|
||||
$this->column_order = $columnOrder;
|
||||
$this->doc_filter = $docFilter;
|
||||
|
||||
// if data is empty the pagination is handled with query in database
|
||||
if (empty($data)) {
|
||||
$this->handlePagination = false;
|
||||
}
|
||||
parent::__construct(
|
||||
$tableName,
|
||||
null,
|
||||
null,
|
||||
$column,
|
||||
$itemsPerPage,
|
||||
$direction
|
||||
);
|
||||
$this->table_data = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get table data to show on current page.
|
||||
*
|
||||
* @see SortableTable#get_table_data
|
||||
*/
|
||||
public function get_table_data(
|
||||
$from = 1,
|
||||
$perPage = null,
|
||||
$column = null,
|
||||
$direction = null,
|
||||
$sort = true
|
||||
) {
|
||||
$table = TableSort::sort_table_config(
|
||||
$this->table_data,
|
||||
$this->column,
|
||||
'ASC' === $this->direction ? SORT_ASC : SORT_DESC,
|
||||
$this->column_show,
|
||||
$this->column_order,
|
||||
SORT_REGULAR,
|
||||
$this->doc_filter
|
||||
);
|
||||
|
||||
if ($this->handlePagination) {
|
||||
return array_slice($table, $from, $this->per_page);
|
||||
}
|
||||
|
||||
return $table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get total number of items.
|
||||
*
|
||||
* @see SortableTable#get_total_number_of_items
|
||||
*/
|
||||
public function get_total_number_of_items()
|
||||
{
|
||||
if (!empty($this->total_number_of_items) && $this->total_number_of_items !== -1) {
|
||||
return $this->total_number_of_items;
|
||||
} else {
|
||||
if (!empty($this->table_data)) {
|
||||
return count($this->table_data);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
214
main/inc/lib/StudentFollowPage.php
Normal file
214
main/inc/lib/StudentFollowPage.php
Normal file
@@ -0,0 +1,214 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use Chamilo\CourseBundle\Entity\CItemProperty;
|
||||
|
||||
/**
|
||||
* Class StudentFollowPage.
|
||||
*/
|
||||
class StudentFollowPage
|
||||
{
|
||||
public const VARIABLE_ACQUISITION = 'acquisition';
|
||||
public const VARIABLE_INVISIBLE = 'invisible';
|
||||
|
||||
public static function getLpSubscription(
|
||||
array $lpInfo,
|
||||
int $studentId,
|
||||
int $courseId,
|
||||
int $sessionId = 0,
|
||||
bool $showTeacherName = true
|
||||
): string {
|
||||
$em = Database::getManager();
|
||||
|
||||
if ($lpInfo['subscribe_users']) {
|
||||
$itemRepo = $em->getRepository(CItemProperty::class);
|
||||
$itemProperty = $itemRepo->findByUserSuscribedToItem(
|
||||
'learnpath',
|
||||
$lpInfo['iid'],
|
||||
$studentId,
|
||||
$courseId,
|
||||
$sessionId
|
||||
);
|
||||
|
||||
if (null === $itemProperty) {
|
||||
$userGroups = GroupManager::getAllGroupPerUserSubscription($studentId, $courseId);
|
||||
|
||||
foreach ($userGroups as $groupInfo) {
|
||||
$itemProperty = $itemRepo->findByGroupSuscribedToLp(
|
||||
'learnpath',
|
||||
$lpInfo['iid'],
|
||||
$groupInfo['iid'],
|
||||
$courseId,
|
||||
$sessionId
|
||||
);
|
||||
|
||||
if (null !== $itemProperty) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (null === $itemProperty) {
|
||||
return '-';
|
||||
}
|
||||
|
||||
$formattedDate = api_convert_and_format_date($itemProperty->getInsertDate(), DATE_TIME_FORMAT_LONG);
|
||||
|
||||
if ($showTeacherName) {
|
||||
$insertUser = $itemProperty->getInsertUser()->getId() !== $studentId
|
||||
? $itemProperty->getInsertUser()->getCompleteName()
|
||||
: '-';
|
||||
|
||||
return "$insertUser<br>".Display::tag('small', $formattedDate);
|
||||
}
|
||||
|
||||
return $formattedDate;
|
||||
}
|
||||
|
||||
$subscriptionEvent = Event::findUserSubscriptionToCourse($studentId, $courseId, $sessionId);
|
||||
|
||||
if (empty($subscriptionEvent)) {
|
||||
return '-';
|
||||
}
|
||||
|
||||
$formattedDate = api_convert_and_format_date($subscriptionEvent['default_date'], DATE_TIME_FORMAT_LONG);
|
||||
|
||||
if ($showTeacherName) {
|
||||
$creator = api_get_user_entity($subscriptionEvent['default_user_id']);
|
||||
|
||||
return "{$creator->getCompleteName()}<br>".Display::tag('small', $formattedDate);
|
||||
}
|
||||
|
||||
return $formattedDate;
|
||||
}
|
||||
|
||||
public static function getLpAcquisition(
|
||||
array $lpInfo,
|
||||
int $studentId,
|
||||
int $courseId,
|
||||
int $sessionId = 0,
|
||||
bool $allowEdit = false
|
||||
): string {
|
||||
$lpView = learnpath::findLastView($lpInfo['iid'], $studentId, $courseId, $sessionId, true);
|
||||
|
||||
$extraField = new ExtraField('lp_view');
|
||||
$field = $extraField->get_handler_field_info_by_field_variable(self::VARIABLE_ACQUISITION);
|
||||
|
||||
$extraFieldValue = new ExtraFieldValue('lp_view');
|
||||
$value = $extraFieldValue->get_values_by_handler_and_field_variable($lpView['iid'], self::VARIABLE_ACQUISITION);
|
||||
|
||||
$return = '';
|
||||
|
||||
if (empty($value)) {
|
||||
$return .= '-';
|
||||
} else {
|
||||
$optionSelected = array_filter(
|
||||
$field['options'],
|
||||
function (array $option) use ($value) {
|
||||
return $option['option_value'] == $value['value'];
|
||||
}
|
||||
);
|
||||
|
||||
if (empty($optionSelected)) {
|
||||
$return .= '-';
|
||||
} else {
|
||||
$optionSelected = current($optionSelected);
|
||||
$valueComment = json_decode($value['comment'], true);
|
||||
|
||||
$register = api_get_user_entity($valueComment['user']);
|
||||
|
||||
$return .= ExtraFieldOption::translateDisplayName($optionSelected['display_text']).'<br>'
|
||||
.Display::tag('small', $register->getCompleteName()).'<br>'
|
||||
.Display::tag(
|
||||
'small',
|
||||
api_convert_and_format_date($valueComment['datetime'], DATE_TIME_FORMAT_LONG)
|
||||
).'<br>';
|
||||
}
|
||||
}
|
||||
|
||||
$editUrl = api_get_path(WEB_AJAX_PATH).'student_follow_page.ajax.php?'
|
||||
.http_build_query(['lp_view' => $lpView['iid'], 'a' => 'form_adquisition']);
|
||||
|
||||
if ($allowEdit) {
|
||||
$return .= Display::url(
|
||||
Display::return_icon('edit.png', get_lang('Edit'), [], ICON_SIZE_TINY),
|
||||
$editUrl,
|
||||
['class' => 'ajax', 'data-title' => strip_tags($lpInfo['lp_name'])]
|
||||
);
|
||||
}
|
||||
|
||||
return '<div id="acquisition-'.$lpView['iid'].'">'.$return.'</div>';
|
||||
}
|
||||
|
||||
public static function getLpVisibleScript()
|
||||
{
|
||||
$url = api_get_path(WEB_AJAX_PATH).'student_follow_page.ajax.php?'.http_build_query(['a' => 'views_invisible']);
|
||||
|
||||
return "<script>$(function () {
|
||||
var chkbView = $('[name=\"chkb_view[]\"]');
|
||||
|
||||
function doRequest(element, state) {
|
||||
element.prop('disabled', true);
|
||||
|
||||
var views = $.makeArray(element).map(function (input) { return input.value; });
|
||||
|
||||
return $.post('$url', { 'chkb_view[]': views, 'state': state }, function () { element.prop('disabled', false); });
|
||||
}
|
||||
|
||||
$('[name=\"chkb_category[]\"]').on('change', function () {
|
||||
var checked = this.checked;
|
||||
var chkbs = $(this).parents('table').find('td :checkbox').each(function () { this.checked = checked; });
|
||||
|
||||
doRequest(chkbs, checked);
|
||||
}).prop('checked', true);
|
||||
|
||||
chkbView.on('change', function () {
|
||||
doRequest($(this), this.checked);
|
||||
|
||||
$(this).parents('table').find('th :checkbox').prop(
|
||||
'checked',
|
||||
$.makeArray($(this).parents('table').find('td :checkbox'))
|
||||
.map(function (input) { return input.checked; })
|
||||
.reduce(function (acc, cur) { return acc && cur; })
|
||||
);
|
||||
}).each(function () {
|
||||
if (!this.checked) {
|
||||
$(this).parents('table').find('th :checkbox').prop('checked', false);
|
||||
}
|
||||
});
|
||||
});</script>";
|
||||
}
|
||||
|
||||
public static function getLpVisibleField(array $lpInfo, int $studentId, int $courseId, int $sessionId = 0)
|
||||
{
|
||||
$attrs = [];
|
||||
|
||||
$isVisible = self::isViewVisible($lpInfo['iid'], $studentId, $courseId, $sessionId);
|
||||
|
||||
if (!$isVisible) {
|
||||
$attrs['checked'] = 'checked';
|
||||
}
|
||||
|
||||
return Display::input(
|
||||
'checkbox',
|
||||
'chkb_view[]',
|
||||
implode('_', [$lpInfo['iid'], $studentId, $courseId, $sessionId]),
|
||||
$attrs
|
||||
);
|
||||
}
|
||||
|
||||
public static function isViewVisible(int $lpId, int $studentId, int $courseId, int $sessionId): bool
|
||||
{
|
||||
$lpView = learnpath::findLastView($lpId, $studentId, $courseId, $sessionId);
|
||||
|
||||
if (empty($lpView)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$extraFieldValue = new ExtraFieldValue('lp_view');
|
||||
$value = $extraFieldValue->get_values_by_handler_and_field_variable($lpView['iid'], self::VARIABLE_INVISIBLE);
|
||||
|
||||
return empty($value) || empty($value['value']);
|
||||
}
|
||||
}
|
||||
111
main/inc/lib/TeacherTimeReport.php
Normal file
111
main/inc/lib/TeacherTimeReport.php
Normal file
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Library for generate a teacher time report.
|
||||
*
|
||||
* @author Angel Fernando Quiroz Campos <angel.quiroz@beeznest.com>
|
||||
*/
|
||||
class TeacherTimeReport
|
||||
{
|
||||
/**
|
||||
* The report data.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $data = [];
|
||||
|
||||
/**
|
||||
* Callback for compare sessions names.
|
||||
*
|
||||
* @param array $dataA The data A
|
||||
* @param array $dataB The data B
|
||||
*
|
||||
* @return int returns -1 if dataA is less than dataB, 1 if dataA is greater than dataB, and 0 if they are equal
|
||||
*/
|
||||
public function compareSessions($dataA, $dataB)
|
||||
{
|
||||
return strnatcmp($dataA['session']['name'], $dataB['session']['name']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for compare courses names.
|
||||
*
|
||||
* @param array $dataA The datab A
|
||||
* @param array $dataB The data B
|
||||
*
|
||||
* @return int returns -1 if dataA is less than dataB, 1 if dataA is greater than dataB, and 0 if they are equal
|
||||
*/
|
||||
public function compareCourses($dataA, $dataB)
|
||||
{
|
||||
return strnatcmp($dataA['course']['name'], $dataB['course']['name']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for compare coaches names.
|
||||
*
|
||||
* @param array $dataA The datab A
|
||||
* @param array $dataB The data B
|
||||
*
|
||||
* @return int returns -1 if dataA is less than dataB, 1 if dataA is greater than dataB, and 0 if they are equal
|
||||
*/
|
||||
public function compareCoaches($dataA, $dataB)
|
||||
{
|
||||
return strnatcmp($dataA['coach']['complete_name'], $dataB['coach']['complete_name']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort the report data.
|
||||
*
|
||||
* @param bool $withFilter Whether sort by sessions and courses
|
||||
*/
|
||||
public function sortData($withFilter = false)
|
||||
{
|
||||
if ($withFilter) {
|
||||
uasort($this->data, [$this, 'compareSessions']);
|
||||
uasort($this->data, [$this, 'compareCourses']);
|
||||
}
|
||||
|
||||
uasort($this->data, [$this, 'compareCoaches']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool|false $withFilter
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function prepareDataToExport($withFilter = false)
|
||||
{
|
||||
$dataToExport = [];
|
||||
|
||||
if ($withFilter) {
|
||||
$dataToExport[] = [
|
||||
get_lang('Session'),
|
||||
get_lang('Course'),
|
||||
get_lang('Coach'),
|
||||
get_lang('TotalTime'),
|
||||
];
|
||||
} else {
|
||||
$dataToExport[] = [
|
||||
get_lang('Coach'),
|
||||
get_lang('TotalTime'),
|
||||
];
|
||||
}
|
||||
|
||||
foreach ($this->data as $row) {
|
||||
$data = [];
|
||||
|
||||
if ($withFilter) {
|
||||
$data[] = $row['session']['name'];
|
||||
$data[] = $row['course']['name'];
|
||||
}
|
||||
|
||||
$data[] = $row['coach']['complete_name'];
|
||||
$data[] = $row['total_time'];
|
||||
|
||||
$dataToExport[] = $data;
|
||||
}
|
||||
|
||||
return $dataToExport;
|
||||
}
|
||||
}
|
||||
2591
main/inc/lib/TicketManager.php
Normal file
2591
main/inc/lib/TicketManager.php
Normal file
File diff suppressed because it is too large
Load Diff
1609
main/inc/lib/TrackingCourseLog.php
Normal file
1609
main/inc/lib/TrackingCourseLog.php
Normal file
File diff suppressed because it is too large
Load Diff
121
main/inc/lib/UnserializeApi.php
Normal file
121
main/inc/lib/UnserializeApi.php
Normal file
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Class UnserializeApi.
|
||||
*/
|
||||
class UnserializeApi
|
||||
{
|
||||
/**
|
||||
* Unserialize content using Brummann\Polyfill\Unserialize.
|
||||
*
|
||||
* @param string $type
|
||||
* @param string $serialized
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function unserialize($type, $serialized, $ignoreErrors = false)
|
||||
{
|
||||
$allowedClasses = [];
|
||||
|
||||
switch ($type) {
|
||||
case 'career':
|
||||
case 'sequence_graph':
|
||||
$allowedClasses = [
|
||||
\Fhaculty\Graph\Graph::class,
|
||||
\Fhaculty\Graph\Set\VerticesMap::class,
|
||||
\Fhaculty\Graph\Set\Vertices::class,
|
||||
\Fhaculty\Graph\Set\Edges::class,
|
||||
\Fhaculty\Graph\Vertex::class,
|
||||
\Fhaculty\Graph\Edge\Base::class,
|
||||
\Fhaculty\Graph\Edge\Directed::class,
|
||||
\Fhaculty\Graph\Edge\Undirected::class,
|
||||
];
|
||||
break;
|
||||
case 'course':
|
||||
$allowedClasses = [
|
||||
\Chamilo\CourseBundle\Component\CourseCopy\Course::class,
|
||||
\Chamilo\CourseBundle\Component\CourseCopy\Resources\Announcement::class,
|
||||
\Chamilo\CourseBundle\Component\CourseCopy\Resources\Asset::class,
|
||||
\Chamilo\CourseBundle\Component\CourseCopy\Resources\Attendance::class,
|
||||
\Chamilo\CourseBundle\Component\CourseCopy\Resources\CalendarEvent::class,
|
||||
\Chamilo\CourseBundle\Component\CourseCopy\Resources\CourseCopyLearnpath::class,
|
||||
\Chamilo\CourseBundle\Component\CourseCopy\Resources\CourseCopyTestCategory::class,
|
||||
\Chamilo\CourseBundle\Component\CourseCopy\Resources\CourseDescription::class,
|
||||
\Chamilo\CourseBundle\Component\CourseCopy\Resources\CourseSession::class,
|
||||
\Chamilo\CourseBundle\Component\CourseCopy\Resources\Document::class,
|
||||
\Chamilo\CourseBundle\Component\CourseCopy\Resources\Forum::class,
|
||||
\Chamilo\CourseBundle\Component\CourseCopy\Resources\ForumCategory::class,
|
||||
\Chamilo\CourseBundle\Component\CourseCopy\Resources\ForumPost::class,
|
||||
\Chamilo\CourseBundle\Component\CourseCopy\Resources\ForumTopic::class,
|
||||
\Chamilo\CourseBundle\Component\CourseCopy\Resources\Glossary::class,
|
||||
\Chamilo\CourseBundle\Component\CourseCopy\Resources\GradeBookBackup::class,
|
||||
\Chamilo\CourseBundle\Component\CourseCopy\Resources\LearnPathCategory::class,
|
||||
\Chamilo\CourseBundle\Component\CourseCopy\Resources\Link::class,
|
||||
\Chamilo\CourseBundle\Component\CourseCopy\Resources\LinkCategory::class,
|
||||
\Chamilo\CourseBundle\Component\CourseCopy\Resources\Quiz::class,
|
||||
\Chamilo\CourseBundle\Component\CourseCopy\Resources\QuizQuestion::class,
|
||||
\Chamilo\CourseBundle\Component\CourseCopy\Resources\QuizQuestionOption::class,
|
||||
\Chamilo\CourseBundle\Component\CourseCopy\Resources\ScormDocument::class,
|
||||
\Chamilo\CourseBundle\Component\CourseCopy\Resources\Survey::class,
|
||||
\Chamilo\CourseBundle\Component\CourseCopy\Resources\SurveyInvitation::class,
|
||||
\Chamilo\CourseBundle\Component\CourseCopy\Resources\SurveyQuestion::class,
|
||||
\Chamilo\CourseBundle\Component\CourseCopy\Resources\Thematic::class,
|
||||
\Chamilo\CourseBundle\Component\CourseCopy\Resources\ToolIntro::class,
|
||||
\Chamilo\CourseBundle\Component\CourseCopy\Resources\Wiki::class,
|
||||
\Chamilo\CourseBundle\Component\CourseCopy\Resources\Work::class,
|
||||
\Chamilo\CourseBundle\Component\CourseCopy\Resources\XapiTool::class,
|
||||
\Chamilo\CourseBundle\Entity\CLpCategory::class,
|
||||
stdClass::class,
|
||||
Category::class,
|
||||
AttendanceLink::class,
|
||||
DropboxLink::class,
|
||||
Evaluation::class,
|
||||
ExerciseLink::class,
|
||||
ForumThreadLink::class,
|
||||
LearnpathLink::class,
|
||||
LinkFactory::class,
|
||||
Result::class,
|
||||
StudentPublicationLink::class,
|
||||
SurveyLink::class,
|
||||
];
|
||||
// no break
|
||||
case 'lp':
|
||||
$allowedClasses = array_merge(
|
||||
$allowedClasses,
|
||||
[
|
||||
learnpath::class,
|
||||
learnpathItem::class,
|
||||
aicc::class,
|
||||
aiccBlock::class,
|
||||
aiccItem::class,
|
||||
aiccObjective::class,
|
||||
aiccResource::class,
|
||||
scorm::class,
|
||||
scormItem::class,
|
||||
scormMetadata::class,
|
||||
scormOrganization::class,
|
||||
scormResource::class,
|
||||
Link::class,
|
||||
LpItem::class,
|
||||
]
|
||||
);
|
||||
break;
|
||||
case 'not_allowed_classes':
|
||||
default:
|
||||
$allowedClasses = false;
|
||||
}
|
||||
|
||||
if ($ignoreErrors) {
|
||||
return @unserialize(
|
||||
$serialized,
|
||||
['allowed_classes' => $allowedClasses]
|
||||
);
|
||||
}
|
||||
|
||||
return unserialize(
|
||||
$serialized,
|
||||
['allowed_classes' => $allowedClasses]
|
||||
);
|
||||
}
|
||||
}
|
||||
96
main/inc/lib/VideoChat.php
Normal file
96
main/inc/lib/VideoChat.php
Normal file
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* VideoChat class.
|
||||
*
|
||||
* This class provides methods for video chat management.
|
||||
*
|
||||
* @author Angel Fernando Quiroz Campos <angel.quiroz@beeznest.com>
|
||||
*/
|
||||
class VideoChat
|
||||
{
|
||||
/**
|
||||
* Get the video chat info by its users.
|
||||
*
|
||||
* @param int $user1 User id
|
||||
* @param int $user2 Other user id
|
||||
*
|
||||
* @return array The video chat info. Otherwise return false
|
||||
*/
|
||||
public static function getChatRoomByUsers($user1, $user2)
|
||||
{
|
||||
$user1 = (int) $user1;
|
||||
$user2 = (int) $user2;
|
||||
|
||||
if (empty($user1) || empty($user2)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return Database::select(
|
||||
'*',
|
||||
Database::get_main_table(TABLE_MAIN_CHAT_VIDEO),
|
||||
[
|
||||
'where' => [
|
||||
'(from_user = ? AND to_user = ?)' => [$user1, $user2],
|
||||
'OR (from_user = ? AND to_user = ?)' => [$user2, $user1],
|
||||
],
|
||||
],
|
||||
'first'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a video chat.
|
||||
*
|
||||
* @param int $fromUser The sender user
|
||||
* @param int $toUser The receiver user
|
||||
*
|
||||
* @return int The created video chat id. Otherwise return false
|
||||
*/
|
||||
public static function createRoom($fromUser, $toUser)
|
||||
{
|
||||
$fromUserInfo = api_get_user_info($fromUser);
|
||||
$toUserInfo = api_get_user_info($toUser);
|
||||
|
||||
$chatName = vsprintf(
|
||||
get_lang('VideoChatBetweenUserXAndUserY'),
|
||||
[$fromUserInfo['firstname'], $toUserInfo['firstname']]
|
||||
);
|
||||
|
||||
return Database::insert(
|
||||
Database::get_main_table(TABLE_MAIN_CHAT_VIDEO),
|
||||
[
|
||||
'from_user' => $fromUser,
|
||||
'to_user' => $toUser,
|
||||
'room_name' => $chatName,
|
||||
'datetime' => api_get_utc_datetime(),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the video chat exists by its room name.
|
||||
*
|
||||
* @param string $name The video chat name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function nameExists($name)
|
||||
{
|
||||
$resultData = Database::select(
|
||||
'COUNT(1) AS count',
|
||||
Database::get_main_table(TABLE_MAIN_CHAT_VIDEO),
|
||||
[
|
||||
'where' => ['room_name = ?' => $name],
|
||||
],
|
||||
'first'
|
||||
);
|
||||
|
||||
if ($resultData !== false) {
|
||||
return $resultData['count'] > 0;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
/**
|
||||
* Definition of the Accessurleditcoursestourl class.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Access_url_edit_courses_to_url class
|
||||
* Contains several functions dealing with displaying,
|
||||
* editing,... of a Access_url_edit_courses_to_url_functions.
|
||||
*
|
||||
* @version 1.0
|
||||
*
|
||||
* @author Toon Keppens <toon@vi-host.net>
|
||||
* @author Julio Montoya - Cleaning code
|
||||
* @author Ricardo Rodriguez - Separated the function and code
|
||||
*/
|
||||
class Accessurleditcoursestourl
|
||||
{
|
||||
/**
|
||||
* Search for a list of available courses by title or code, based on
|
||||
* a given string.
|
||||
*
|
||||
* @param string String to search for
|
||||
* @param int Deprecated param
|
||||
*
|
||||
* @return xajaxResponse A formatted, xajax answer block
|
||||
* @assert () === false
|
||||
*/
|
||||
public function search_courses($needle, $id)
|
||||
{
|
||||
$tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
|
||||
$xajax_response = new xajaxResponse();
|
||||
$return = '';
|
||||
|
||||
if (!empty($needle)) {
|
||||
// xajax send utf8 datas... datas in db can be non-utf8 datas
|
||||
$charset = api_get_system_encoding();
|
||||
$needle = api_convert_encoding($needle, $charset, 'utf-8');
|
||||
$needle = Database::escape_string($needle);
|
||||
// search courses where username or firstname or lastname begins likes $needle
|
||||
$sql = 'SELECT id, code, title FROM '.$tbl_course.' u '.
|
||||
' WHERE (title LIKE "'.$needle.'%" '.
|
||||
' OR code LIKE "'.$needle.'%" '.
|
||||
' ) '.
|
||||
' ORDER BY title, code '.
|
||||
' LIMIT 11';
|
||||
$rs = Database::query($sql);
|
||||
$i = 0;
|
||||
while ($course = Database::fetch_array($rs)) {
|
||||
$i++;
|
||||
if ($i <= 10) {
|
||||
$return .= '<a href="javascript: void(0);" onclick="javascript: add_course_to_url('.addslashes($course['id']).',\''.addslashes($course['title']).' ('.addslashes($course['code']).')'.'\')">'.$course['title'].' ('.$course['code'].')</a><br />';
|
||||
} else {
|
||||
$return .= '...<br />';
|
||||
}
|
||||
}
|
||||
}
|
||||
$xajax_response->addAssign(
|
||||
'ajax_list_courses',
|
||||
'innerHTML',
|
||||
api_utf8_encode($return)
|
||||
);
|
||||
|
||||
return $xajax_response;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
/**
|
||||
* Definition of the Accessurleditsessiontourl class.
|
||||
*/
|
||||
require_once 'xajax/xajax.inc.php';
|
||||
|
||||
/**
|
||||
* Accessurleditsessiontourl class
|
||||
* Contains several functions dealing with displaying,
|
||||
* editing,... of a Access_url_edit_session_to_url_functions.
|
||||
*
|
||||
* @version 1.0
|
||||
*
|
||||
* @author Toon Keppens <toon@vi-host.net>
|
||||
* @author Julio Montoya - Cleaning code
|
||||
* @author Ricardo Rodriguez - Separated the function and code
|
||||
*/
|
||||
class Accessurleditsessionstourl
|
||||
{
|
||||
/**
|
||||
* Search sessions by name, based on a search string.
|
||||
*
|
||||
* @param string Search string
|
||||
* @param int Deprecated param
|
||||
*
|
||||
* @return string Xajax response block
|
||||
* @assert () === false
|
||||
*/
|
||||
public function search_sessions($needle, $id)
|
||||
{
|
||||
$tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
|
||||
$xajax_response = new xajaxResponse();
|
||||
$return = '';
|
||||
|
||||
if (!empty($needle)) {
|
||||
// xajax send utf8 datas... datas in db can be non-utf8 datas
|
||||
$charset = api_get_system_encoding();
|
||||
$needle = api_convert_encoding($needle, $charset, 'utf-8');
|
||||
$needle = Database::escape_string($needle);
|
||||
// search sessiones where username or firstname or lastname begins likes $needle
|
||||
$sql = 'SELECT id, name FROM '.$tbl_session.' u
|
||||
WHERE (name LIKE "'.$needle.'%")
|
||||
ORDER BY name, id
|
||||
LIMIT 11';
|
||||
$rs = Database::query($sql);
|
||||
$i = 0;
|
||||
while ($session = Database::fetch_array($rs)) {
|
||||
$i++;
|
||||
if ($i <= 10) {
|
||||
$return .= '<a href="#" onclick="add_user_to_url(\''.addslashes($session['id']).'\',\''.addslashes($session['name']).' ('.addslashes($session['id']).')'.'\')">'.$session['name'].' </a><br />';
|
||||
} else {
|
||||
$return .= '...<br />';
|
||||
}
|
||||
}
|
||||
}
|
||||
$xajax_response->addAssign(
|
||||
'ajax_list_courses',
|
||||
'innerHTML',
|
||||
api_utf8_encode($return)
|
||||
);
|
||||
|
||||
return $xajax_response;
|
||||
}
|
||||
}
|
||||
65
main/inc/lib/access_url_edit_users_to_url_functions.lib.php
Normal file
65
main/inc/lib/access_url_edit_users_to_url_functions.lib.php
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* AccessUrlEditUsersToUrl class definition
|
||||
* Contains several functions dealing with displaying,
|
||||
* editing,... of a Access_url_edit_users_to_url_functions.
|
||||
*
|
||||
* @version 1.0
|
||||
*
|
||||
* @author Toon Keppens <toon@vi-host.net>
|
||||
* @author Julio Montoya - Cleaning code
|
||||
* @author Ricardo Rodriguez - Separated the function and code
|
||||
*/
|
||||
class AccessUrlEditUsersToUrl
|
||||
{
|
||||
/**
|
||||
* Search users by username, firstname or lastname, based on the given
|
||||
* search string.
|
||||
*
|
||||
* @param string Search string
|
||||
* @param int Deprecated param
|
||||
*
|
||||
* @return xajaxResponse Xajax response block
|
||||
* @assert () === false
|
||||
*/
|
||||
public static function search_users($needle, $id)
|
||||
{
|
||||
$tbl_user = Database::get_main_table(TABLE_MAIN_USER);
|
||||
$xajax_response = new xajaxResponse();
|
||||
$return = '';
|
||||
if (!empty($needle)) {
|
||||
// xajax send utf8 datas... datas in db can be non-utf8 datas
|
||||
$charset = api_get_system_encoding();
|
||||
$needle = api_convert_encoding($needle, $charset, 'utf-8');
|
||||
$needle = Database::escape_string($needle);
|
||||
// search users where username or firstname or lastname begins likes $needle
|
||||
$order_clause = api_sort_by_first_name() ? ' ORDER BY firstname, lastname, username' : ' ORDER BY lastname, firstname, username';
|
||||
$sql = 'SELECT u.user_id, username, lastname, firstname FROM '.$tbl_user.' u '.
|
||||
' WHERE (username LIKE "'.$needle.'%" '.
|
||||
' OR firstname LIKE "'.$needle.'%" '.
|
||||
' OR lastname LIKE "'.$needle.'%") '.
|
||||
$order_clause.
|
||||
' LIMIT 11';
|
||||
$rs = Database::query($sql);
|
||||
$i = 0;
|
||||
|
||||
while ($user = Database::fetch_array($rs)) {
|
||||
$i++;
|
||||
if ($i <= 10) {
|
||||
$return .= '<a href="javascript: void(0);" onclick="javascript: add_user_to_url(\''.addslashes($user['user_id']).'\',\''.api_get_person_name(addslashes($user['firstname']), addslashes($user['lastname'])).' ('.addslashes($user['username']).')'.'\')">'.api_get_person_name($user['firstname'], $user['lastname']).' ('.$user['username'].')</a><br />';
|
||||
} else {
|
||||
$return .= '...<br />';
|
||||
}
|
||||
}
|
||||
}
|
||||
$xajax_response->addAssign(
|
||||
'ajax_list_users',
|
||||
'innerHTML',
|
||||
api_utf8_encode($return)
|
||||
);
|
||||
|
||||
return $xajax_response;
|
||||
}
|
||||
}
|
||||
1485
main/inc/lib/add_course.lib.inc.php
Normal file
1485
main/inc/lib/add_course.lib.inc.php
Normal file
File diff suppressed because it is too large
Load Diff
132
main/inc/lib/add_courses_to_session_functions.lib.php
Normal file
132
main/inc/lib/add_courses_to_session_functions.lib.php
Normal file
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use ChamiloSession as Session;
|
||||
|
||||
/**
|
||||
* Class AddCourseToSession.
|
||||
*/
|
||||
class AddCourseToSession
|
||||
{
|
||||
/**
|
||||
* Searches a course, given a search string and a type of search box.
|
||||
*
|
||||
* @param string $needle Search string
|
||||
* @param string $type Type of search box ('single' or anything else)
|
||||
* @param int $id_session
|
||||
*
|
||||
* @return xajaxResponse XajaxResponse
|
||||
* @assert ('abc', 'single') !== null
|
||||
* @assert ('abc', 'multiple') !== null
|
||||
*/
|
||||
public static function search_courses($needle, $type, $id_session)
|
||||
{
|
||||
$tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
|
||||
// Session value set in file add_courses_to_session.php
|
||||
$id_session = (int) $id_session;
|
||||
$tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
|
||||
$course_title = null;
|
||||
$xajax_response = new xajaxResponse();
|
||||
$return = '';
|
||||
if (!empty($needle) && !empty($type)) {
|
||||
// xajax send utf8 datas... datas in db can be non-utf8 datas
|
||||
$charset = api_get_system_encoding();
|
||||
$needle = api_convert_encoding($needle, $charset, 'utf-8');
|
||||
$needle = Database::escape_string($needle);
|
||||
|
||||
$cond_course_code = '';
|
||||
if (!empty($id_session)) {
|
||||
$id_session = (int) $id_session;
|
||||
// check course_code from session_rel_course table
|
||||
$sql = 'SELECT c_id FROM '.$tbl_session_rel_course.'
|
||||
WHERE session_id = '.$id_session;
|
||||
$res = Database::query($sql);
|
||||
$course_codes = '';
|
||||
if (Database::num_rows($res) > 0) {
|
||||
while ($row = Database::fetch_row($res)) {
|
||||
$course_codes .= '\''.$row[0].'\',';
|
||||
}
|
||||
$course_codes = substr($course_codes, 0, (strlen($course_codes) - 1));
|
||||
$cond_course_code = ' AND course.id NOT IN('.$course_codes.') ';
|
||||
}
|
||||
}
|
||||
|
||||
if ('single' == $type) {
|
||||
// search users where username or firstname or lastname begins likes $needle
|
||||
$sql = 'SELECT
|
||||
course.id,
|
||||
course.visual_code,
|
||||
course.title,
|
||||
session_rel_course.session_id
|
||||
FROM '.$tbl_course.' course
|
||||
LEFT JOIN '.$tbl_session_rel_course.' session_rel_course
|
||||
ON course.id = session_rel_course.c_id
|
||||
AND session_rel_course.session_id = '.intval($id_session).'
|
||||
WHERE
|
||||
course.visual_code LIKE "'.$needle.'%" OR
|
||||
course.title LIKE "'.$needle.'%"';
|
||||
} else {
|
||||
$sql = 'SELECT course.id, course.visual_code, course.title
|
||||
FROM '.$tbl_course.' course
|
||||
WHERE
|
||||
course.visual_code LIKE "'.$needle.'%" '.$cond_course_code.'
|
||||
ORDER BY course.code ';
|
||||
}
|
||||
|
||||
if (api_is_multiple_url_enabled()) {
|
||||
$tbl_course_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
|
||||
$access_url_id = api_get_current_access_url_id();
|
||||
if (-1 != $access_url_id) {
|
||||
if ('single' == $type) {
|
||||
$sql = 'SELECT
|
||||
course.id,
|
||||
course.visual_code,
|
||||
course.title,
|
||||
session_rel_course.session_id
|
||||
FROM '.$tbl_course.' course
|
||||
LEFT JOIN '.$tbl_session_rel_course.' session_rel_course
|
||||
ON course.id = session_rel_course.c_id
|
||||
AND session_rel_course.session_id = '.intval($id_session).'
|
||||
INNER JOIN '.$tbl_course_rel_access_url.' url_course
|
||||
ON (url_course.c_id = course.id)
|
||||
WHERE
|
||||
access_url_id = '.$access_url_id.' AND
|
||||
(course.visual_code LIKE "'.$needle.'%" OR
|
||||
course.title LIKE "'.$needle.'%" )';
|
||||
} else {
|
||||
$sql = 'SELECT course.id, course.visual_code, course.title
|
||||
FROM '.$tbl_course.' course, '.$tbl_course_rel_access_url.' url_course
|
||||
WHERE
|
||||
url_course.c_id = course.id AND
|
||||
access_url_id = '.$access_url_id.' AND
|
||||
course.visual_code LIKE "'.$needle.'%" '.$cond_course_code.'
|
||||
ORDER BY course.code ';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$rs = Database::query($sql);
|
||||
$course_list = [];
|
||||
if ('single' == $type) {
|
||||
while ($course = Database::fetch_array($rs)) {
|
||||
$course_list[] = $course['id'];
|
||||
$course_title = str_replace("'", "\'", $course_title);
|
||||
$return .= '<a href="javascript: void(0);" onclick="javascript: add_course_to_session(\''.$course['id'].'\',\''.$course_title.' ('.$course['visual_code'].')'.'\')">'.$course['title'].' ('.$course['visual_code'].')</a><br />';
|
||||
}
|
||||
$xajax_response->addAssign('ajax_list_courses_single', 'innerHTML', api_utf8_encode($return));
|
||||
} else {
|
||||
$return .= '<select id="origin" name="NoSessionCoursesList[]" multiple="multiple" size="20" style="width:340px;">';
|
||||
while ($course = Database::fetch_array($rs)) {
|
||||
$course_list[] = $course['id'];
|
||||
$course_title = str_replace("'", "\'", $course_title);
|
||||
$return .= '<option value="'.$course['id'].'" title="'.htmlspecialchars($course['title'].' ('.$course['visual_code'].')', ENT_QUOTES).'">'.$course['title'].' ('.$course['visual_code'].')</option>';
|
||||
}
|
||||
$return .= '</select>';
|
||||
$xajax_response->addAssign('ajax_list_courses_multiple', 'innerHTML', api_utf8_encode($return));
|
||||
}
|
||||
}
|
||||
Session::write('course_list', $course_list);
|
||||
|
||||
return $xajax_response;
|
||||
}
|
||||
}
|
||||
5386
main/inc/lib/agenda.lib.php
Normal file
5386
main/inc/lib/agenda.lib.php
Normal file
File diff suppressed because it is too large
Load Diff
10701
main/inc/lib/api.lib.php
Normal file
10701
main/inc/lib/api.lib.php
Normal file
File diff suppressed because it is too large
Load Diff
106
main/inc/lib/app_view.php
Normal file
106
main/inc/lib/app_view.php
Normal file
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Class View.
|
||||
*
|
||||
* @deprecated use Template class
|
||||
*/
|
||||
class View
|
||||
{
|
||||
private $data;
|
||||
private $template;
|
||||
private $layout;
|
||||
private $tool_path;
|
||||
|
||||
/**
|
||||
* Constructor, init tool path for rendering.
|
||||
*
|
||||
* @deprecated
|
||||
*
|
||||
* @param string $toolname tool name (optional)
|
||||
* @param string $template_path
|
||||
*/
|
||||
public function __construct($toolname = '', $template_path = null)
|
||||
{
|
||||
if (!empty($toolname)) {
|
||||
if (isset($template_path)) {
|
||||
$path = $template_path.$toolname.'/';
|
||||
} else {
|
||||
$path = api_get_path(SYS_CODE_PATH).$toolname.'/';
|
||||
}
|
||||
if (is_dir($path)) {
|
||||
$this->tool_path = $path;
|
||||
} else {
|
||||
throw new Exception('View::__construct() $path directory does not exist '.$path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set data sent from a controller.
|
||||
*
|
||||
* @param array data
|
||||
*/
|
||||
public function set_data($data)
|
||||
{
|
||||
if (!is_array($data)) {
|
||||
throw new Exception('View::set_data() $data must to be an array, you have sent a'.gettype($data));
|
||||
}
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set layout view sent from a controller.
|
||||
*
|
||||
* @param string $layout view
|
||||
*/
|
||||
public function set_layout($layout)
|
||||
{
|
||||
$this->layout = $layout;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set template view sent from a controller.
|
||||
*
|
||||
* @param string $template view
|
||||
*/
|
||||
public function set_template($template)
|
||||
{
|
||||
$this->template = $template;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render data to the template and layout views.
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
$content = $this->render_template();
|
||||
$target = $this->tool_path.$this->layout.'.php';
|
||||
if (file_exists($target)) {
|
||||
require_once $target;
|
||||
} else {
|
||||
throw new Exception('View::render() invalid file path '.$target);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* It's used into render method for rendering data in the template and layout views.
|
||||
*
|
||||
* @return string Rendered template (as HTML, most of the time)
|
||||
*/
|
||||
private function render_template()
|
||||
{
|
||||
$target = $this->tool_path.$this->template.'.php';
|
||||
if (file_exists($target)) {
|
||||
ob_start();
|
||||
@extract($this->data, EXTR_OVERWRITE); //pass the $this->data array into local scope
|
||||
require_once $target;
|
||||
$content = ob_get_clean();
|
||||
|
||||
return $content;
|
||||
} else {
|
||||
throw new Exception('View::render_template() invalid file path '.$target);
|
||||
}
|
||||
}
|
||||
}
|
||||
152
main/inc/lib/array.lib.php
Normal file
152
main/inc/lib/array.lib.php
Normal file
@@ -0,0 +1,152 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
/**
|
||||
* This is the array library for Chamilo.
|
||||
* Include/require it in your code to use its functionality.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Removes duplicate values from a dimensional array.
|
||||
*
|
||||
* @param array $array dimensional array
|
||||
*
|
||||
* @return array an array with unique values
|
||||
*/
|
||||
function array_unique_dimensional($array)
|
||||
{
|
||||
if (!is_array($array)) {
|
||||
return $array;
|
||||
}
|
||||
|
||||
foreach ($array as &$myvalue) {
|
||||
$myvalue = serialize($myvalue);
|
||||
}
|
||||
|
||||
$array = array_unique($array);
|
||||
|
||||
foreach ($array as &$myvalue) {
|
||||
$myvalue = UnserializeApi::unserialize('not_allowed_clases', $myvalue);
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort multidimensional arrays.
|
||||
*
|
||||
* @param array unsorted multidimensional array
|
||||
* @param string key to be sorted
|
||||
*
|
||||
* @return array result array
|
||||
*
|
||||
* @author found in http://php.net/manual/en/function.sort.php
|
||||
*/
|
||||
function msort($array, $id = 'id', $order = 'desc')
|
||||
{
|
||||
if (empty($array)) {
|
||||
return $array;
|
||||
}
|
||||
$temp_array = [];
|
||||
while (count($array) > 0) {
|
||||
$lowest_id = 0;
|
||||
$index = 0;
|
||||
foreach ($array as $item) {
|
||||
if ('desc' == $order) {
|
||||
if (strip_tags($item[$id]) < strip_tags($array[$lowest_id][$id])) {
|
||||
$lowest_id = $index;
|
||||
}
|
||||
} else {
|
||||
if (isset($item[$id]) && strip_tags($item[$id]) > strip_tags($array[$lowest_id][$id])) {
|
||||
$lowest_id = $index;
|
||||
}
|
||||
}
|
||||
$index++;
|
||||
}
|
||||
$temp_array[] = $array[$lowest_id];
|
||||
$array = array_merge(
|
||||
array_slice($array, 0, $lowest_id),
|
||||
array_slice($array, $lowest_id + 1)
|
||||
);
|
||||
}
|
||||
|
||||
return $temp_array;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $array
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
function utf8_sort($array)
|
||||
{
|
||||
$old_locale = setlocale(LC_ALL, 0);
|
||||
$code = api_get_language_isocode();
|
||||
$locale_list = [$code.'.utf8', 'en.utf8', 'en_US.utf8', 'en_GB.utf8'];
|
||||
$try_sort = false;
|
||||
|
||||
foreach ($locale_list as $locale) {
|
||||
$my_local = setlocale(LC_COLLATE, $locale);
|
||||
if ($my_local) {
|
||||
$try_sort = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($try_sort) {
|
||||
uasort($array, 'strcoll');
|
||||
}
|
||||
setlocale(LC_COLLATE, $old_locale);
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $array
|
||||
* @param string $separator
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function array_to_string($array, $separator = ',')
|
||||
{
|
||||
if (empty($array)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return implode($separator.' ', $array);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
function array_flatten(array $array)
|
||||
{
|
||||
$flatten = [];
|
||||
array_walk_recursive(
|
||||
$array,
|
||||
function ($value) use (&$flatten) {
|
||||
$flatten[] = $value;
|
||||
}
|
||||
);
|
||||
|
||||
return $flatten;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shuffles an array keeping the associations.
|
||||
*
|
||||
* @param $array
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function shuffle_assoc(&$array)
|
||||
{
|
||||
$keys = array_keys($array);
|
||||
shuffle($keys);
|
||||
$new = [];
|
||||
foreach ($keys as $key) {
|
||||
$new[$key] = $array[$key];
|
||||
}
|
||||
$array = $new;
|
||||
|
||||
return true;
|
||||
}
|
||||
2958
main/inc/lib/attendance.lib.php
Normal file
2958
main/inc/lib/attendance.lib.php
Normal file
File diff suppressed because it is too large
Load Diff
399
main/inc/lib/auth.lib.php
Normal file
399
main/inc/lib/auth.lib.php
Normal file
@@ -0,0 +1,399 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Class Auth
|
||||
* Auth can be used to instantiate objects or as a library to manage courses
|
||||
* This file contains a class used like library provides functions for auth tool.
|
||||
* It's also used like model to courses_controller (MVC pattern).
|
||||
*
|
||||
* @author Christian Fasanando <christian1827@gmail.com>
|
||||
*/
|
||||
class Auth
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* This function get all the courses in the particular user category.
|
||||
*
|
||||
* @param bool $hidePrivate
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getCoursesInCategory($hidePrivate = true)
|
||||
{
|
||||
$user_id = api_get_user_id();
|
||||
|
||||
$TABLECOURS = Database::get_main_table(TABLE_MAIN_COURSE);
|
||||
$TABLECOURSUSER = Database::get_main_table(TABLE_MAIN_COURSE_USER);
|
||||
$avoidCoursesCondition = CoursesAndSessionsCatalog::getAvoidCourseCondition();
|
||||
$showCoursesCondition = CoursesAndSessionsCatalog::getCoursesToShowInCatalogueCondition();
|
||||
$visibilityCondition = CourseManager::getCourseVisibilitySQLCondition('course', true, $hidePrivate);
|
||||
|
||||
$sql = "SELECT
|
||||
course.id as real_id,
|
||||
course.code, course.visual_code, course.subscribe subscr, course.unsubscribe unsubscr,
|
||||
course.title title, course.tutor_name tutor, course.directory, 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.user_id = '".$user_id."' AND
|
||||
course_rel_user.relation_type <> ".COURSE_RELATION_TYPE_RRHH."
|
||||
$avoidCoursesCondition
|
||||
$showCoursesCondition
|
||||
$visibilityCondition
|
||||
ORDER BY course_rel_user.user_course_cat, course_rel_user.sort ASC";
|
||||
$result = Database::query($sql);
|
||||
$data = [];
|
||||
while ($course = Database::fetch_array($result)) {
|
||||
$data[$course['user_course_cat']][] = $course;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* stores the changes in a course category
|
||||
* (moving a course to a different course category).
|
||||
*
|
||||
* @param int $courseId
|
||||
* @param int Category id
|
||||
*
|
||||
* @return bool True if it success
|
||||
*/
|
||||
public function updateCourseCategory($courseId, $newcategory)
|
||||
{
|
||||
$courseId = (int) $courseId;
|
||||
$newcategory = (int) $newcategory;
|
||||
$current_user = api_get_user_id();
|
||||
|
||||
$table = Database::get_main_table(TABLE_MAIN_COURSE_USER);
|
||||
$max_sort_value = api_max_sort_value($newcategory, $current_user);
|
||||
$sql = "UPDATE $table SET
|
||||
user_course_cat='".$newcategory."',
|
||||
sort='".($max_sort_value + 1)."'
|
||||
WHERE
|
||||
c_id ='".$courseId."' AND
|
||||
user_id='".$current_user."' AND
|
||||
relation_type<>".COURSE_RELATION_TYPE_RRHH;
|
||||
$resultQuery = Database::query($sql);
|
||||
|
||||
$result = false;
|
||||
if (Database::affected_rows($resultQuery)) {
|
||||
$result = true;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* moves the course one place up or down.
|
||||
*
|
||||
* @param string Direction (up/down)
|
||||
* @param string Course code
|
||||
* @param int Category id
|
||||
*
|
||||
* @return bool True if it success
|
||||
*/
|
||||
public function move_course($direction, $course2move, $category)
|
||||
{
|
||||
$table = Database::get_main_table(TABLE_MAIN_COURSE_USER);
|
||||
|
||||
$current_user_id = api_get_user_id();
|
||||
$all_user_courses = CourseManager::getCoursesByUserCourseCategory($current_user_id);
|
||||
|
||||
// we need only the courses of the category we are moving in
|
||||
$user_courses = [];
|
||||
foreach ($all_user_courses as $key => $course) {
|
||||
if ($course['user_course_category'] == $category) {
|
||||
$user_courses[] = $course;
|
||||
}
|
||||
}
|
||||
|
||||
$target_course = [];
|
||||
foreach ($user_courses as $count => $course) {
|
||||
if ($course2move == $course['code']) {
|
||||
// source_course is the course where we clicked the up or down icon
|
||||
$source_course = $course;
|
||||
// target_course is the course before/after the source_course (depending on the up/down icon)
|
||||
if ('up' == $direction) {
|
||||
$target_course = $user_courses[$count - 1];
|
||||
} else {
|
||||
$target_course = $user_courses[$count + 1];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$result = false;
|
||||
if (count($target_course) > 0 && count($source_course) > 0) {
|
||||
$courseInfo = api_get_course_info($source_course['code']);
|
||||
$courseId = $courseInfo['real_id'];
|
||||
|
||||
$targetCourseInfo = api_get_course_info($target_course['code']);
|
||||
$targetCourseId = $targetCourseInfo['real_id'];
|
||||
|
||||
$sql = "UPDATE $table
|
||||
SET sort='".$target_course['sort']."'
|
||||
WHERE
|
||||
c_id = '".$courseId."' AND
|
||||
user_id = '".$current_user_id."' AND
|
||||
relation_type<>".COURSE_RELATION_TYPE_RRHH;
|
||||
|
||||
$result1 = Database::query($sql);
|
||||
|
||||
$sql = "UPDATE $table SET sort='".$source_course['sort']."'
|
||||
WHERE
|
||||
c_id ='".$targetCourseId."' AND
|
||||
user_id='".$current_user_id."' AND
|
||||
relation_type<>".COURSE_RELATION_TYPE_RRHH;
|
||||
|
||||
$result2 = Database::query($sql);
|
||||
|
||||
if (Database::affected_rows($result1) && Database::affected_rows($result2)) {
|
||||
$result = true;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the course one place up or down.
|
||||
*
|
||||
* @param string $direction Direction up/down
|
||||
* @param string $category2move Category id
|
||||
*
|
||||
* @return bool True If it success
|
||||
*/
|
||||
public function move_category($direction, $category2move)
|
||||
{
|
||||
$userId = api_get_user_id();
|
||||
$userCategories = CourseManager::get_user_course_categories($userId);
|
||||
$categories = array_values($userCategories);
|
||||
|
||||
$previous = null;
|
||||
$target_category = [];
|
||||
foreach ($categories as $key => $category) {
|
||||
$category_id = $category['id'];
|
||||
if ($category2move == $category_id) {
|
||||
// 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 ('up' == $direction) {
|
||||
if (isset($categories[$key - 1])) {
|
||||
$target_category = $userCategories[$categories[$key - 1]['id']];
|
||||
}
|
||||
} else {
|
||||
if (isset($categories[$key + 1])) {
|
||||
$target_category = $userCategories[$categories[$key + 1]['id']];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$result = false;
|
||||
if (count($target_category) > 0 && count($source_category) > 0) {
|
||||
$table = Database::get_main_table(TABLE_USER_COURSE_CATEGORY);
|
||||
$sql = "UPDATE $table SET
|
||||
sort = '".Database::escape_string($target_category['sort'])."'
|
||||
WHERE id='".intval($source_category['id'])."' AND user_id='".$userId."'";
|
||||
$resultFirst = Database::query($sql);
|
||||
$sql = "UPDATE $table SET
|
||||
sort = '".Database::escape_string($source_category['sort'])."'
|
||||
WHERE id='".intval($target_category['id'])."' AND user_id='".$userId."'";
|
||||
$resultSecond = Database::query($sql);
|
||||
if (Database::affected_rows($resultFirst) && Database::affected_rows($resultSecond)) {
|
||||
$result = true;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the user course category in the chamilo_user database.
|
||||
*
|
||||
* @param string Category title
|
||||
* @param int Category id
|
||||
*
|
||||
* @return bool True if it success
|
||||
*/
|
||||
public function store_edit_course_category($title, $category_id)
|
||||
{
|
||||
$title = Database::escape_string($title);
|
||||
$category_id = (int) $category_id;
|
||||
$result = false;
|
||||
$table = Database::get_main_table(TABLE_USER_COURSE_CATEGORY);
|
||||
$sql = "UPDATE $table
|
||||
SET title='".api_htmlentities($title, ENT_QUOTES, api_get_system_encoding())."'
|
||||
WHERE id='".$category_id."'";
|
||||
$resultQuery = Database::query($sql);
|
||||
if (Database::affected_rows($resultQuery)) {
|
||||
$result = true;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* deletes a course category and moves all the courses that were in this category to main category.
|
||||
*
|
||||
* @param int Category id
|
||||
*
|
||||
* @return bool True if it success
|
||||
*/
|
||||
public function delete_course_category($category_id)
|
||||
{
|
||||
$current_user_id = api_get_user_id();
|
||||
$tucc = Database::get_main_table(TABLE_USER_COURSE_CATEGORY);
|
||||
$TABLECOURSUSER = Database::get_main_table(TABLE_MAIN_COURSE_USER);
|
||||
$category_id = (int) $category_id;
|
||||
$result = false;
|
||||
$sql = "DELETE FROM $tucc
|
||||
WHERE
|
||||
id='".$category_id."' AND
|
||||
user_id='".$current_user_id."'";
|
||||
$resultQuery = Database::query($sql);
|
||||
if (Database::affected_rows($resultQuery)) {
|
||||
$result = true;
|
||||
}
|
||||
$sql = "UPDATE $TABLECOURSUSER
|
||||
SET user_course_cat='0'
|
||||
WHERE
|
||||
user_course_cat='".$category_id."' AND
|
||||
user_id='".$current_user_id."' AND
|
||||
relation_type<>".COURSE_RELATION_TYPE_RRHH." ";
|
||||
Database::query($sql);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $categoryId
|
||||
*
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function getUserCourseCategory($categoryId)
|
||||
{
|
||||
$userId = api_get_user_id();
|
||||
$tucc = Database::get_main_table(TABLE_USER_COURSE_CATEGORY);
|
||||
$categoryId = (int) $categoryId;
|
||||
|
||||
$sql = "SELECT * FROM $tucc
|
||||
WHERE
|
||||
id= $categoryId AND
|
||||
user_id= $userId";
|
||||
$resultQuery = Database::query($sql);
|
||||
|
||||
return Database::fetch_array($resultQuery, 'ASSOC');
|
||||
}
|
||||
|
||||
/**
|
||||
* unsubscribe the user from a given course.
|
||||
*
|
||||
* @param string $course_code
|
||||
*
|
||||
* @return bool True if it success
|
||||
*/
|
||||
public function remove_user_from_course($course_code, $sessionId = 0)
|
||||
{
|
||||
$tbl_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
|
||||
|
||||
// protect variables
|
||||
$current_user_id = api_get_user_id();
|
||||
$course_code = Database::escape_string($course_code);
|
||||
|
||||
$courseInfo = api_get_course_info($course_code);
|
||||
|
||||
if (empty($courseInfo) || empty($current_user_id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if course can be unsubscribe.
|
||||
if ('1' !== $courseInfo['unsubscribe']) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$courseId = $courseInfo['real_id'];
|
||||
|
||||
// we check (once again) if the user is not course administrator
|
||||
// because the course administrator cannot unsubscribe himself
|
||||
// (s)he can only delete the course
|
||||
$sql = "SELECT * FROM $tbl_course_user
|
||||
WHERE
|
||||
user_id='".$current_user_id."' AND
|
||||
c_id ='".$courseId."' AND
|
||||
status='1' ";
|
||||
$result_check = Database::query($sql);
|
||||
$number_of_rows = Database::num_rows($result_check);
|
||||
|
||||
$result = true;
|
||||
if ($number_of_rows > 0) {
|
||||
$result = false;
|
||||
}
|
||||
|
||||
if ($result) {
|
||||
CourseManager::unsubscribe_user($current_user_id, $course_code, $sessionId);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* stores the user course category in the chamilo_user database.
|
||||
*
|
||||
* @param string Category title
|
||||
*
|
||||
* @return bool True if it success
|
||||
*/
|
||||
public function store_course_category($category_title)
|
||||
{
|
||||
$table = Database::get_main_table(TABLE_USER_COURSE_CATEGORY);
|
||||
|
||||
// protect data
|
||||
$current_user_id = api_get_user_id();
|
||||
$category_title = Database::escape_string($category_title);
|
||||
|
||||
// step 1: we determine the max value of the user defined course categories
|
||||
$sql = "SELECT sort FROM $table
|
||||
WHERE user_id='".$current_user_id."'
|
||||
ORDER BY sort DESC";
|
||||
$rs_sort = Database::query($sql);
|
||||
$maxsort = Database::fetch_array($rs_sort);
|
||||
$nextsort = $maxsort['sort'] + 1;
|
||||
|
||||
// step 2: we check if there is already a category with this name,
|
||||
// if not we store it, else we give an error.
|
||||
$sql = "SELECT * FROM $table
|
||||
WHERE
|
||||
user_id='".$current_user_id."' AND
|
||||
title='".$category_title."'
|
||||
ORDER BY sort DESC";
|
||||
$rs = Database::query($sql);
|
||||
|
||||
$result = false;
|
||||
if (0 == Database::num_rows($rs)) {
|
||||
$sql = "INSERT INTO $table (user_id, title,sort)
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
176
main/inc/lib/baker.lib.php
Normal file
176
main/inc/lib/baker.lib.php
Normal file
@@ -0,0 +1,176 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Php library to Bake the PNG Images.
|
||||
*/
|
||||
class PNGImageBaker
|
||||
{
|
||||
private $_contents;
|
||||
private $_size;
|
||||
private $_chunks;
|
||||
|
||||
/**
|
||||
* Prepares file for handling metadata.
|
||||
* Verifies that this file is a valid PNG file.
|
||||
* Unpacks file chunks and reads them into an array.
|
||||
*
|
||||
* @param string $contents File content as a string
|
||||
*/
|
||||
public function __construct($contents)
|
||||
{
|
||||
$this->_contents = $contents;
|
||||
$png_signature = pack("C8", 137, 80, 78, 71, 13, 10, 26, 10);
|
||||
// Read 8 bytes of PNG header and verify.
|
||||
$header = substr($this->_contents, 0, 8);
|
||||
if ($header != $png_signature) {
|
||||
echo 'This is not a valid PNG image';
|
||||
}
|
||||
$this->_size = strlen($this->_contents);
|
||||
$this->_chunks = [];
|
||||
// Skip 8 bytes of IHDR image header.
|
||||
$position = 8;
|
||||
do {
|
||||
$chunk = @unpack('Nsize/a4type', substr($this->_contents, $position, 8));
|
||||
$this->_chunks[$chunk['type']][] = substr($this->_contents, $position + 8, $chunk['size']);
|
||||
// Skip 12 bytes chunk overhead.
|
||||
$position += $chunk['size'] + 12;
|
||||
} while ($position < $this->_size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a key already exists in the chunk of said type.
|
||||
* We need to avoid writing same keyword into file chunks.
|
||||
*
|
||||
* @param string $type chunk type, like iTXt, tEXt, etc
|
||||
* @param string $check keyword that needs to be checked
|
||||
*
|
||||
* @return bool (true|false) True if file is safe to write this keyword, false otherwise
|
||||
*/
|
||||
public function checkChunks($type, $check)
|
||||
{
|
||||
if (array_key_exists($type, $this->_chunks)) {
|
||||
foreach (array_keys($this->_chunks[$type]) as $typekey) {
|
||||
list($key, $data) = explode("\0", $this->_chunks[$type][$typekey]);
|
||||
if (0 == strcmp($key, $check)) {
|
||||
echo 'Key "'.$check.'" already exists in "'.$type.'" chunk.';
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a chunk by type with given key and text.
|
||||
*
|
||||
* @param string $chunkType chunk type, like iTXt, tEXt, etc
|
||||
* @param string $key keyword that needs to be added
|
||||
* @param string $value currently an assertion URL that is added to an image metadata
|
||||
*
|
||||
* @return string $result file content with a new chunk as a string
|
||||
*/
|
||||
public function addChunk($chunkType, $key, $value)
|
||||
{
|
||||
$chunkData = $key."\0".$value;
|
||||
$crc = pack("N", crc32($chunkType.$chunkData));
|
||||
$len = pack("N", strlen($chunkData));
|
||||
|
||||
$newChunk = $len.$chunkType.$chunkData.$crc;
|
||||
$result = substr($this->_contents, 0, $this->_size - 12)
|
||||
.$newChunk
|
||||
.substr($this->_contents, $this->_size - 12, 12);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* removes a chunk by type with given key and text.
|
||||
*
|
||||
* @param string $chunkType chunk type, like iTXt, tEXt, etc
|
||||
* @param string $key keyword that needs to be deleted
|
||||
* @param string $png the png image
|
||||
*
|
||||
* @return string $result new File content
|
||||
*/
|
||||
public function removeChunks($chunkType, $key, $png)
|
||||
{
|
||||
// Read the magic bytes and verify
|
||||
$retval = substr($png, 0, 8);
|
||||
$ipos = 8;
|
||||
if ($retval != "\x89PNG\x0d\x0a\x1a\x0a") {
|
||||
throw new Exception('Is not a valid PNG image');
|
||||
}
|
||||
// Loop through the chunks. Byte 0-3 is length, Byte 4-7 is type
|
||||
$chunkHeader = substr($png, $ipos, 8);
|
||||
$ipos = $ipos + 8;
|
||||
while ($chunkHeader) {
|
||||
// Extract length and type from binary data
|
||||
$chunk = @unpack('Nsize/a4type', $chunkHeader);
|
||||
$skip = false;
|
||||
if ($chunk['type'] == $chunkType) {
|
||||
$data = substr($png, $ipos, $chunk['size']);
|
||||
$sections = explode("\0", $data);
|
||||
print_r($sections);
|
||||
if ($sections[0] == $key) {
|
||||
$skip = true;
|
||||
}
|
||||
}
|
||||
// Extract the data and the CRC
|
||||
$data = substr($png, $ipos, $chunk['size'] + 4);
|
||||
$ipos = $ipos + $chunk['size'] + 4;
|
||||
// Add in the header, data, and CRC
|
||||
if (!$skip) {
|
||||
$retval = $retval.$chunkHeader.$data;
|
||||
}
|
||||
// Read next chunk header
|
||||
$chunkHeader = substr($png, $ipos, 8);
|
||||
$ipos = $ipos + 8;
|
||||
}
|
||||
|
||||
return $retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the baked PNG info by the Key.
|
||||
*
|
||||
* @param string $png the png image
|
||||
* @param string $key keyword that needs to be searched
|
||||
*
|
||||
* @return mixed - If there is an error - boolean false is returned
|
||||
* If there is PNG information that matches the key an array is returned
|
||||
*/
|
||||
public function extractBadgeInfo($png, $key = 'openbadges')
|
||||
{
|
||||
// Read the magic bytes and verify
|
||||
$retval = substr($png, 0, 8);
|
||||
$ipos = 8;
|
||||
if ("\x89PNG\x0d\x0a\x1a\x0a" != $retval) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Loop through the chunks. Byte 0-3 is length, Byte 4-7 is type
|
||||
$chunkHeader = substr($png, $ipos, 8);
|
||||
$ipos = $ipos + 8;
|
||||
while ($chunkHeader) {
|
||||
// Extract length and type from binary data
|
||||
$chunk = @unpack('Nsize/a4type', $chunkHeader);
|
||||
$skip = false;
|
||||
if ('tEXt' == $chunk['type']) {
|
||||
$data = substr($png, $ipos, $chunk['size']);
|
||||
$sections = explode("\0", $data);
|
||||
if ($sections[0] == $key) {
|
||||
return $sections;
|
||||
}
|
||||
}
|
||||
// Extract the data and the CRC
|
||||
$data = substr($png, $ipos, $chunk['size'] + 4);
|
||||
$ipos = $ipos + $chunk['size'] + 4;
|
||||
|
||||
// Read next chunk header
|
||||
$chunkHeader = substr($png, $ipos, 8);
|
||||
$ipos = $ipos + 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
1085
main/inc/lib/banner.lib.php
Normal file
1085
main/inc/lib/banner.lib.php
Normal file
File diff suppressed because it is too large
Load Diff
3306
main/inc/lib/blog.lib.php
Normal file
3306
main/inc/lib/blog.lib.php
Normal file
File diff suppressed because it is too large
Load Diff
1221
main/inc/lib/browser/Browser.php
Normal file
1221
main/inc/lib/browser/Browser.php
Normal file
File diff suppressed because it is too large
Load Diff
1570
main/inc/lib/career.lib.php
Normal file
1570
main/inc/lib/career.lib.php
Normal file
File diff suppressed because it is too large
Load Diff
955
main/inc/lib/certificate.lib.php
Normal file
955
main/inc/lib/certificate.lib.php
Normal file
@@ -0,0 +1,955 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use Endroid\QrCode\ErrorCorrectionLevel;
|
||||
use Endroid\QrCode\QrCode;
|
||||
|
||||
/**
|
||||
* Certificate Class
|
||||
* Generate certificates based in the gradebook tool.
|
||||
*/
|
||||
class Certificate extends Model
|
||||
{
|
||||
public $table;
|
||||
public $columns = [
|
||||
'id',
|
||||
'cat_id',
|
||||
'score_certificate',
|
||||
'created_at',
|
||||
'path_certificate',
|
||||
];
|
||||
/**
|
||||
* Certification data.
|
||||
*/
|
||||
public $certificate_data = [];
|
||||
|
||||
/**
|
||||
* Student's certification path.
|
||||
*/
|
||||
public $certification_user_path = null;
|
||||
public $certification_web_user_path = null;
|
||||
public $html_file = null;
|
||||
public $qr_file = null;
|
||||
public $user_id;
|
||||
|
||||
/** If true every time we enter to the certificate URL
|
||||
* we would generate a new certificate (good thing because we can edit the
|
||||
* certificate and all users will have the latest certificate bad because we.
|
||||
* load the certificate every time */
|
||||
public $force_certificate_generation = true;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param int $certificate_id ID of the certificate
|
||||
* @param int $userId
|
||||
* @param bool $sendNotification send message to student
|
||||
* @param bool $updateCertificateData
|
||||
*
|
||||
* If no ID given, take user_id and try to generate one
|
||||
*/
|
||||
public function __construct(
|
||||
$certificate_id = 0,
|
||||
$userId = 0,
|
||||
$sendNotification = false,
|
||||
$updateCertificateData = true
|
||||
) {
|
||||
$this->table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CERTIFICATE);
|
||||
$this->user_id = !empty($userId) ? $userId : api_get_user_id();
|
||||
|
||||
if (!empty($certificate_id)) {
|
||||
$certificate = $this->get($certificate_id);
|
||||
if (!empty($certificate) && is_array($certificate)) {
|
||||
$this->certificate_data = $certificate;
|
||||
$this->user_id = $this->certificate_data['user_id'];
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->user_id) {
|
||||
// Need to be called before any operation
|
||||
$this->check_certificate_path();
|
||||
// To force certification generation
|
||||
if ($this->force_certificate_generation) {
|
||||
$this->generate([], $sendNotification);
|
||||
}
|
||||
if (isset($this->certificate_data) && $this->certificate_data) {
|
||||
if (empty($this->certificate_data['path_certificate'])) {
|
||||
$this->generate([], $sendNotification);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Setting the qr and html variables
|
||||
if (isset($certificate_id) &&
|
||||
!empty($this->certification_user_path) &&
|
||||
isset($this->certificate_data['path_certificate'])
|
||||
) {
|
||||
$pathinfo = pathinfo($this->certificate_data['path_certificate']);
|
||||
$this->html_file = $this->certification_user_path.basename($this->certificate_data['path_certificate']);
|
||||
$this->qr_file = $this->certification_user_path.$pathinfo['filename'].'_qr.png';
|
||||
} else {
|
||||
$this->check_certificate_path();
|
||||
if (api_get_configuration_value('allow_general_certificate')) {
|
||||
// General certificate
|
||||
$name = md5($this->user_id).'.html';
|
||||
$my_path_certificate = $this->certification_user_path.$name;
|
||||
$path_certificate = '/'.$name;
|
||||
|
||||
// Getting QR filename
|
||||
$file_info = pathinfo($path_certificate);
|
||||
$content = $this->generateCustomCertificate();
|
||||
|
||||
$my_new_content_html = str_replace(
|
||||
'((certificate_barcode))',
|
||||
Display::img(
|
||||
$this->certification_web_user_path.$file_info['filename'].'_qr.png',
|
||||
'QR'
|
||||
),
|
||||
$content
|
||||
);
|
||||
|
||||
$my_new_content_html = mb_convert_encoding(
|
||||
$my_new_content_html,
|
||||
'UTF-8',
|
||||
api_get_system_encoding()
|
||||
);
|
||||
|
||||
$this->html_file = $my_path_certificate;
|
||||
$result = @file_put_contents($my_path_certificate, $my_new_content_html);
|
||||
|
||||
if ($result) {
|
||||
// Updating the path
|
||||
self::updateUserCertificateInfo(
|
||||
0,
|
||||
$this->user_id,
|
||||
$path_certificate,
|
||||
$updateCertificateData
|
||||
);
|
||||
$this->certificate_data['path_certificate'] = $path_certificate;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the certificate user path directory is created.
|
||||
*/
|
||||
public function check_certificate_path()
|
||||
{
|
||||
$this->certification_user_path = null;
|
||||
|
||||
// Setting certification path
|
||||
$path_info = UserManager::getUserPathById($this->user_id, 'system');
|
||||
$web_path_info = UserManager::getUserPathById($this->user_id, 'web');
|
||||
|
||||
if (!empty($path_info) && isset($path_info)) {
|
||||
$this->certification_user_path = $path_info.'certificate/';
|
||||
$this->certification_web_user_path = $web_path_info.'certificate/';
|
||||
$mode = api_get_permissions_for_new_directories();
|
||||
if (!is_dir($path_info)) {
|
||||
mkdir($path_info, $mode, true);
|
||||
}
|
||||
if (!is_dir($this->certification_user_path)) {
|
||||
mkdir($this->certification_user_path, $mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the current certificate object. This is generally triggered by
|
||||
* the teacher from the gradebook tool to re-generate the certificate because
|
||||
* the original version wa flawed.
|
||||
*
|
||||
* @param bool $force_delete
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function delete($force_delete = false)
|
||||
{
|
||||
$delete_db = false;
|
||||
if (!empty($this->certificate_data)) {
|
||||
if (!is_null($this->html_file) || $this->html_file != '' || strlen($this->html_file)) {
|
||||
// Deleting HTML file
|
||||
if (is_file($this->html_file)) {
|
||||
@unlink($this->html_file);
|
||||
if (is_file($this->html_file) === false) {
|
||||
$delete_db = true;
|
||||
} else {
|
||||
$delete_db = false;
|
||||
}
|
||||
}
|
||||
// Deleting QR code PNG image file
|
||||
if (is_file($this->qr_file)) {
|
||||
@unlink($this->qr_file);
|
||||
}
|
||||
if ($delete_db || $force_delete) {
|
||||
return parent::delete($this->certificate_data['id']);
|
||||
}
|
||||
} else {
|
||||
return parent::delete($this->certificate_data['id']);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an HTML Certificate and fills the path_certificate field in the DB.
|
||||
*
|
||||
* @param array $params
|
||||
* @param bool $sendNotification
|
||||
*
|
||||
* @return bool|int
|
||||
*/
|
||||
public function generate($params = [], $sendNotification = false)
|
||||
{
|
||||
// The user directory should be set
|
||||
if (empty($this->certification_user_path) &&
|
||||
$this->force_certificate_generation === false
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$params['hide_print_button'] = isset($params['hide_print_button']) ? true : false;
|
||||
$categoryId = 0;
|
||||
$my_category = [];
|
||||
if (isset($this->certificate_data) && isset($this->certificate_data['cat_id'])) {
|
||||
$categoryId = $this->certificate_data['cat_id'];
|
||||
$my_category = Category::load($categoryId);
|
||||
}
|
||||
|
||||
if (isset($my_category[0]) && !empty($categoryId) &&
|
||||
$my_category[0]->is_certificate_available($this->user_id)
|
||||
) {
|
||||
/** @var Category $category */
|
||||
$category = $my_category[0];
|
||||
|
||||
$courseInfo = api_get_course_info($category->get_course_code());
|
||||
$courseId = $courseInfo['real_id'];
|
||||
$sessionId = $category->get_session_id();
|
||||
|
||||
$skill = new Skill();
|
||||
$skill->addSkillToUser(
|
||||
$this->user_id,
|
||||
$category,
|
||||
$courseId,
|
||||
$sessionId
|
||||
);
|
||||
|
||||
if (is_dir($this->certification_user_path)) {
|
||||
if (!empty($this->certificate_data)) {
|
||||
$new_content_html = GradebookUtils::get_user_certificate_content(
|
||||
$this->user_id,
|
||||
$category->get_course_code(),
|
||||
$category->get_session_id(),
|
||||
false,
|
||||
$params['hide_print_button']
|
||||
);
|
||||
|
||||
if ($category->get_id() == $categoryId) {
|
||||
$name = $this->certificate_data['path_certificate'];
|
||||
$myPathCertificate = $this->certification_user_path.basename($name);
|
||||
|
||||
if (file_exists($myPathCertificate) &&
|
||||
!empty($name) &&
|
||||
!is_dir($myPathCertificate) &&
|
||||
$this->force_certificate_generation == false
|
||||
) {
|
||||
// Seems that the file was already generated
|
||||
return true;
|
||||
} else {
|
||||
// Creating new name
|
||||
$name = md5($this->user_id.$this->certificate_data['cat_id']).'.html';
|
||||
$myPathCertificate = $this->certification_user_path.$name;
|
||||
$path_certificate = '/'.$name;
|
||||
|
||||
// Getting QR filename
|
||||
$file_info = pathinfo($path_certificate);
|
||||
$qr_code_filename = $this->certification_user_path.$file_info['filename'].'_qr.png';
|
||||
|
||||
$newContent = str_replace(
|
||||
'((certificate_barcode))',
|
||||
Display::img(
|
||||
$this->certification_web_user_path.$file_info['filename'].'_qr.png',
|
||||
'QR'
|
||||
),
|
||||
$new_content_html['content']
|
||||
);
|
||||
|
||||
$newContent = api_convert_encoding(
|
||||
$newContent,
|
||||
'UTF-8',
|
||||
api_get_system_encoding()
|
||||
);
|
||||
|
||||
$result = @file_put_contents($myPathCertificate, $newContent);
|
||||
if ($result) {
|
||||
// Updating the path
|
||||
$this->updateUserCertificateInfo(
|
||||
$this->certificate_data['cat_id'],
|
||||
$this->user_id,
|
||||
$path_certificate
|
||||
);
|
||||
$this->certificate_data['path_certificate'] = $path_certificate;
|
||||
|
||||
if ($this->isHtmlFileGenerated()) {
|
||||
if (!empty($file_info)) {
|
||||
$text = $this->parseCertificateVariables(
|
||||
$new_content_html['variables']
|
||||
);
|
||||
$this->generateQRImage(
|
||||
$text,
|
||||
$qr_code_filename
|
||||
);
|
||||
|
||||
if ($sendNotification) {
|
||||
$subject = get_lang('NotificationCertificateSubject');
|
||||
$message = nl2br(get_lang('NotificationCertificateTemplate'));
|
||||
$score = $this->certificate_data['score_certificate'];
|
||||
self::sendNotification(
|
||||
$subject,
|
||||
$message,
|
||||
api_get_user_info($this->user_id),
|
||||
$courseInfo,
|
||||
[
|
||||
'score_certificate' => $score,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->check_certificate_path();
|
||||
|
||||
// General certificate
|
||||
$name = md5($this->user_id).'.html';
|
||||
$my_path_certificate = $this->certification_user_path.$name;
|
||||
$path_certificate = '/'.$name;
|
||||
|
||||
// Getting QR filename
|
||||
$file_info = pathinfo($path_certificate);
|
||||
$content = $this->generateCustomCertificate();
|
||||
|
||||
$my_new_content_html = str_replace(
|
||||
'((certificate_barcode))',
|
||||
Display::img(
|
||||
$this->certification_web_user_path.$file_info['filename'].'_qr.png',
|
||||
'QR'
|
||||
),
|
||||
$content
|
||||
);
|
||||
|
||||
$my_new_content_html = mb_convert_encoding(
|
||||
$my_new_content_html,
|
||||
'UTF-8',
|
||||
api_get_system_encoding()
|
||||
);
|
||||
|
||||
$result = @file_put_contents($my_path_certificate, $my_new_content_html);
|
||||
|
||||
if ($result) {
|
||||
// Updating the path
|
||||
self::updateUserCertificateInfo(
|
||||
0,
|
||||
$this->user_id,
|
||||
$path_certificate
|
||||
);
|
||||
$this->certificate_data['path_certificate'] = $path_certificate;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function notificationTags()
|
||||
{
|
||||
$tags = [
|
||||
'((course_title))',
|
||||
'((user_first_name))',
|
||||
'((user_last_name))',
|
||||
'((author_first_name))',
|
||||
'((author_last_name))',
|
||||
'((score))',
|
||||
'((portal_name))',
|
||||
'((certificate_link))',
|
||||
];
|
||||
|
||||
return $tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $subject
|
||||
* @param string $message
|
||||
* @param array $userInfo
|
||||
* @param array $courseInfo
|
||||
* @param array $certificateInfo
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function sendNotification(
|
||||
$subject,
|
||||
$message,
|
||||
$userInfo,
|
||||
$courseInfo,
|
||||
$certificateInfo
|
||||
) {
|
||||
if (empty($userInfo) || empty($courseInfo)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$currentUserInfo = api_get_user_info();
|
||||
$url = api_get_path(WEB_PATH).
|
||||
'certificates/index.php?id='.$certificateInfo['id'].'&user_id='.$certificateInfo['user_id'];
|
||||
$link = Display::url($url, $url);
|
||||
|
||||
$replace = [
|
||||
$courseInfo['title'],
|
||||
$userInfo['firstname'],
|
||||
$userInfo['lastname'],
|
||||
$currentUserInfo['firstname'],
|
||||
$currentUserInfo['lastname'],
|
||||
$certificateInfo['score_certificate'],
|
||||
api_get_setting('Institution'),
|
||||
$link,
|
||||
];
|
||||
|
||||
$message = str_replace(self::notificationTags(), $replace, $message);
|
||||
MessageManager::send_message(
|
||||
$userInfo['id'],
|
||||
$subject,
|
||||
$message,
|
||||
[],
|
||||
[],
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
$currentUserInfo['id']
|
||||
);
|
||||
|
||||
$plugin = new AppPlugin();
|
||||
$smsPlugin = $plugin->getSMSPluginLibrary();
|
||||
if ($smsPlugin) {
|
||||
$additionalParameters = [
|
||||
'smsType' => SmsPlugin::CERTIFICATE_NOTIFICATION,
|
||||
'userId' => $userInfo['id'],
|
||||
'direct_message' => $message,
|
||||
];
|
||||
$smsPlugin->send($additionalParameters);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update user info about certificate.
|
||||
*
|
||||
* @param int $categoryId category id
|
||||
* @param int $user_id user id
|
||||
* @param string $path_certificate the path name of the certificate
|
||||
* @param bool $updateCertificateData
|
||||
*/
|
||||
public function updateUserCertificateInfo(
|
||||
$categoryId,
|
||||
$user_id,
|
||||
$path_certificate,
|
||||
$updateCertificateData = true
|
||||
) {
|
||||
$categoryId = (int) $categoryId;
|
||||
$user_id = (int) $user_id;
|
||||
|
||||
if ($updateCertificateData &&
|
||||
!UserManager::is_user_certified($categoryId, $user_id)
|
||||
) {
|
||||
$table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CERTIFICATE);
|
||||
$now = api_get_utc_datetime();
|
||||
$sql = 'UPDATE '.$table.' SET
|
||||
path_certificate="'.Database::escape_string($path_certificate).'",
|
||||
created_at = "'.$now.'"
|
||||
WHERE cat_id = "'.$categoryId.'" AND user_id="'.$user_id.'" ';
|
||||
Database::query($sql);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the file was generated.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isHtmlFileGenerated()
|
||||
{
|
||||
if (empty($this->certification_user_path)) {
|
||||
return false;
|
||||
}
|
||||
if (!empty($this->certificate_data) &&
|
||||
isset($this->certificate_data['path_certificate']) &&
|
||||
!empty($this->certificate_data['path_certificate'])
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a QR code for the certificate. The QR code embeds the text given.
|
||||
*
|
||||
* @param string $text Text to be added in the QR code
|
||||
* @param string $path file path of the image
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function generateQRImage($text, $path)
|
||||
{
|
||||
if (!empty($text) && !empty($path)) {
|
||||
$qrCode = new QrCode($text);
|
||||
//$qrCode->setEncoding('UTF-8');
|
||||
$qrCode->setSize(120);
|
||||
$qrCode->setMargin(5);
|
||||
$qrCode->setWriterByName('png');
|
||||
$qrCode->setErrorCorrectionLevel(ErrorCorrectionLevel::MEDIUM);
|
||||
$qrCode->setForegroundColor(['r' => 0, 'g' => 0, 'b' => 0, 'a' => 0]);
|
||||
$qrCode->setBackgroundColor(['r' => 255, 'g' => 255, 'b' => 255, 'a' => 0]);
|
||||
$qrCode->setValidateResult(false);
|
||||
$qrCode->writeFile($path);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms certificate tags into text values. This function is very static
|
||||
* (it doesn't allow for much flexibility in terms of what tags are printed).
|
||||
*
|
||||
* @param array $array Contains two array entries: first are the headers,
|
||||
* second is an array of contents
|
||||
*
|
||||
* @return string The translated string
|
||||
*/
|
||||
public function parseCertificateVariables($array)
|
||||
{
|
||||
$headers = $array[0];
|
||||
$content = $array[1];
|
||||
$final_content = [];
|
||||
|
||||
if (!empty($content)) {
|
||||
foreach ($content as $key => $value) {
|
||||
$my_header = str_replace(['((', '))'], '', $headers[$key]);
|
||||
$final_content[$my_header] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/* Certificate tags
|
||||
*
|
||||
0 => string '((user_firstname))' (length=18)
|
||||
1 => string '((user_lastname))' (length=17)
|
||||
2 => string '((gradebook_institution))' (length=25)
|
||||
3 => string '((gradebook_sitename))' (length=22)
|
||||
4 => string '((teacher_firstname))' (length=21)
|
||||
5 => string '((teacher_lastname))' (length=20)
|
||||
6 => string '((official_code))' (length=17)
|
||||
7 => string '((date_certificate))' (length=20)
|
||||
8 => string '((course_code))' (length=15)
|
||||
9 => string '((course_title))' (length=16)
|
||||
10 => string '((gradebook_grade))' (length=19)
|
||||
11 => string '((certificate_link))' (length=20)
|
||||
12 => string '((certificate_link_html))' (length=25)
|
||||
13 => string '((certificate_barcode))' (length=23)
|
||||
*/
|
||||
|
||||
$break_space = " \n\r ";
|
||||
$text =
|
||||
$final_content['gradebook_institution'].' - '.
|
||||
$final_content['gradebook_sitename'].' - '.
|
||||
get_lang('Certification').$break_space.
|
||||
get_lang('Student').': '.$final_content['user_firstname'].' '.$final_content['user_lastname'].$break_space.
|
||||
get_lang('Teacher').': '.$final_content['teacher_firstname'].' '.$final_content['teacher_lastname'].$break_space.
|
||||
get_lang('Date').': '.$final_content['date_certificate'].$break_space.
|
||||
get_lang('Score').': '.$final_content['gradebook_grade'].$break_space.
|
||||
'URL'.': '.$final_content['certificate_link'];
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the certificate is visible for the current user
|
||||
* If the global setting allow_public_certificates is set to 'false', no certificate can be printed.
|
||||
* If the global allow_public_certificates is set to 'true' and the course setting allow_public_certificates
|
||||
* is set to 0, no certificate *in this course* can be printed (for anonymous users).
|
||||
* Connected users can always print them.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isVisible()
|
||||
{
|
||||
if (!api_is_anonymous()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (api_get_setting('allow_public_certificates') != 'true') {
|
||||
// The "non-public" setting is set, so do not print
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isset($this->certificate_data, $this->certificate_data['cat_id'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$gradeBook = new Gradebook();
|
||||
$gradeBookInfo = $gradeBook->get($this->certificate_data['cat_id']);
|
||||
|
||||
if (empty($gradeBookInfo['course_code'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$setting = api_get_course_setting(
|
||||
'allow_public_certificates',
|
||||
api_get_course_info($gradeBookInfo['course_code'])
|
||||
);
|
||||
|
||||
if ($setting == 0) {
|
||||
// Printing not allowed
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the certificate is available.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isAvailable()
|
||||
{
|
||||
if (empty($this->certificate_data['path_certificate'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$userCertificate = $this->certification_user_path.basename($this->certificate_data['path_certificate']);
|
||||
|
||||
if (!file_exists($userCertificate)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the student's certificate (HTML file).
|
||||
*/
|
||||
public function show()
|
||||
{
|
||||
$user_certificate = $this->certification_user_path.basename($this->certificate_data['path_certificate']);
|
||||
if (file_exists($user_certificate)) {
|
||||
// Needed in order to browsers don't add custom CSS
|
||||
$certificateContent = '<!DOCTYPE html>';
|
||||
$certificateContent .= (string) file_get_contents($user_certificate);
|
||||
|
||||
// Remove media=screen to be available when printing a document
|
||||
$certificateContent = str_replace(
|
||||
' media="screen"',
|
||||
'',
|
||||
$certificateContent
|
||||
);
|
||||
|
||||
if ($this->user_id == api_get_user_id() &&
|
||||
!empty($this->certificate_data) &&
|
||||
isset($this->certificate_data['id'])
|
||||
) {
|
||||
$certificateId = $this->certificate_data['id'];
|
||||
$extraFieldValue = new ExtraFieldValue('user_certificate');
|
||||
$value = $extraFieldValue->get_values_by_handler_and_field_variable(
|
||||
$certificateId,
|
||||
'downloaded_at'
|
||||
);
|
||||
if (empty($value)) {
|
||||
$params = [
|
||||
'item_id' => $this->certificate_data['id'],
|
||||
'extra_downloaded_at' => api_get_utc_datetime(),
|
||||
];
|
||||
$extraFieldValue->saveFieldValues($params);
|
||||
}
|
||||
}
|
||||
|
||||
header('Content-Type: text/html; charset='.api_get_system_encoding());
|
||||
echo $certificateContent;
|
||||
|
||||
return;
|
||||
}
|
||||
api_not_allowed(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function generateCustomCertificate()
|
||||
{
|
||||
$myCertificate = GradebookUtils::get_certificate_by_user_id(
|
||||
0,
|
||||
$this->user_id
|
||||
);
|
||||
if (empty($myCertificate)) {
|
||||
GradebookUtils::registerUserInfoAboutCertificate(
|
||||
0,
|
||||
$this->user_id,
|
||||
100,
|
||||
api_get_utc_datetime()
|
||||
);
|
||||
}
|
||||
|
||||
$userInfo = api_get_user_info($this->user_id);
|
||||
$extraFieldValue = new ExtraFieldValue('user');
|
||||
$value = $extraFieldValue->get_values_by_handler_and_field_variable($this->user_id, 'legal_accept');
|
||||
$termsValidationDate = '';
|
||||
if (isset($value) && !empty($value['value'])) {
|
||||
list($id, $id2, $termsValidationDate) = explode(':', $value['value']);
|
||||
}
|
||||
|
||||
$sessions = SessionManager::get_sessions_by_user($this->user_id, false, true);
|
||||
$totalTimeInLearningPaths = 0;
|
||||
$sessionsApproved = [];
|
||||
$coursesApproved = [];
|
||||
$courseList = [];
|
||||
|
||||
if ($sessions) {
|
||||
foreach ($sessions as $session) {
|
||||
$allCoursesApproved = [];
|
||||
foreach ($session['courses'] as $course) {
|
||||
$courseInfo = api_get_course_info_by_id($course['real_id']);
|
||||
$courseCode = $courseInfo['code'];
|
||||
$gradebookCategories = Category::load(
|
||||
null,
|
||||
null,
|
||||
$courseCode,
|
||||
null,
|
||||
false,
|
||||
$session['session_id']
|
||||
);
|
||||
|
||||
if (isset($gradebookCategories[0])) {
|
||||
/** @var Category $category */
|
||||
$category = $gradebookCategories[0];
|
||||
$result = Category::userFinishedCourse(
|
||||
$this->user_id,
|
||||
$category,
|
||||
true
|
||||
);
|
||||
|
||||
// Find time spent in LP
|
||||
$timeSpent = Tracking::get_time_spent_in_lp(
|
||||
$this->user_id,
|
||||
$courseCode,
|
||||
[],
|
||||
$session['session_id']
|
||||
);
|
||||
|
||||
if (!isset($courseList[$course['real_id']])) {
|
||||
$courseList[$course['real_id']]['approved'] = false;
|
||||
$courseList[$course['real_id']]['time_spent'] = 0;
|
||||
}
|
||||
|
||||
if ($result) {
|
||||
$courseList[$course['real_id']]['approved'] = true;
|
||||
$coursesApproved[$course['real_id']] = $courseInfo['title'];
|
||||
|
||||
// Find time spent in LP
|
||||
//$totalTimeInLearningPaths += $timeSpent;
|
||||
$allCoursesApproved[] = true;
|
||||
}
|
||||
$courseList[$course['real_id']]['time_spent'] += $timeSpent;
|
||||
}
|
||||
}
|
||||
|
||||
if (count($allCoursesApproved) == count($session['courses'])) {
|
||||
$sessionsApproved[] = $session;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$totalTimeInLearningPaths = 0;
|
||||
foreach ($courseList as $courseId => $courseData) {
|
||||
if ($courseData['approved'] === true) {
|
||||
$totalTimeInLearningPaths += $courseData['time_spent'];
|
||||
}
|
||||
}
|
||||
|
||||
$skill = new Skill();
|
||||
// Ofaj
|
||||
$skills = $skill->getStudentSkills($this->user_id, 2);
|
||||
$timeInSeconds = Tracking::get_time_spent_on_the_platform(
|
||||
$this->user_id,
|
||||
'ever'
|
||||
);
|
||||
$time = api_time_to_hms($timeInSeconds);
|
||||
|
||||
$tplContent = new Template(null, false, false, false, false, false);
|
||||
|
||||
// variables for the default template
|
||||
$tplContent->assign('complete_name', $userInfo['complete_name']);
|
||||
$tplContent->assign('time_in_platform', $time);
|
||||
$tplContent->assign('certificate_generated_date', api_get_local_time($myCertificate['created_at']));
|
||||
if (!empty($termsValidationDate)) {
|
||||
$termsValidationDate = api_get_local_time($termsValidationDate);
|
||||
}
|
||||
$tplContent->assign('terms_validation_date', $termsValidationDate);
|
||||
|
||||
// Ofaj
|
||||
$tplContent->assign('time_in_platform_in_hours', round($timeInSeconds / 3600, 1));
|
||||
$tplContent->assign(
|
||||
'certificate_generated_date_no_time',
|
||||
api_get_local_time(
|
||||
$myCertificate['created_at'],
|
||||
null,
|
||||
null,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
'd-m-Y'
|
||||
)
|
||||
);
|
||||
$tplContent->assign(
|
||||
'terms_validation_date_no_time',
|
||||
api_get_local_time(
|
||||
$termsValidationDate,
|
||||
null,
|
||||
null,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
'd-m-Y'
|
||||
)
|
||||
);
|
||||
$tplContent->assign('skills', $skills);
|
||||
$tplContent->assign('sessions', $sessionsApproved);
|
||||
$tplContent->assign('courses', $coursesApproved);
|
||||
$tplContent->assign('time_spent_in_lps', api_time_to_hms($totalTimeInLearningPaths));
|
||||
$tplContent->assign('time_spent_in_lps_in_hours', round($totalTimeInLearningPaths / 3600, 1));
|
||||
|
||||
$layoutContent = $tplContent->get_template('gradebook/custom_certificate.tpl');
|
||||
$content = $tplContent->fetch($layoutContent);
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ofaj.
|
||||
*/
|
||||
public function generatePdfFromCustomCertificate()
|
||||
{
|
||||
$orientation = api_get_configuration_value('certificate_pdf_orientation');
|
||||
|
||||
$params['orientation'] = 'landscape';
|
||||
if (!empty($orientation)) {
|
||||
$params['orientation'] = $orientation;
|
||||
}
|
||||
|
||||
$params['left'] = 0;
|
||||
$params['right'] = 0;
|
||||
$params['top'] = 0;
|
||||
$params['bottom'] = 0;
|
||||
$page_format = $params['orientation'] == 'landscape' ? 'A4-L' : 'A4';
|
||||
$pdf = new PDF($page_format, $params['orientation'], $params);
|
||||
|
||||
$pdf->html_to_pdf(
|
||||
$this->html_file,
|
||||
get_lang('Certificates'),
|
||||
null,
|
||||
false,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $userId
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getCertificateByUser($userId)
|
||||
{
|
||||
$userId = (int) $userId;
|
||||
if (empty($userId)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CERTIFICATE);
|
||||
$sql = "SELECT * FROM $table
|
||||
WHERE user_id= $userId";
|
||||
$rs = Database::query($sql);
|
||||
|
||||
return Database::store_result($rs, 'ASSOC');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $userId
|
||||
*/
|
||||
public static function generateUserSkills($userId)
|
||||
{
|
||||
$controller = new IndexManager(get_lang('MyCourses'));
|
||||
$courseAndSessions = $controller->returnCoursesAndSessions($userId, true, null, true, false);
|
||||
|
||||
if (isset($courseAndSessions['courses']) && !empty($courseAndSessions['courses'])) {
|
||||
foreach ($courseAndSessions['courses'] as $course) {
|
||||
$cats = Category::load(
|
||||
null,
|
||||
null,
|
||||
$course['code'],
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
false
|
||||
);
|
||||
|
||||
if (isset($cats[0]) && !empty($cats[0])) {
|
||||
Category::generateUserCertificate(
|
||||
$cats[0]->get_id(),
|
||||
$userId
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($courseAndSessions['sessions']) && !empty($courseAndSessions['sessions'])) {
|
||||
foreach ($courseAndSessions['sessions'] as $sessionCategory) {
|
||||
if (isset($sessionCategory['sessions'])) {
|
||||
foreach ($sessionCategory['sessions'] as $sessionData) {
|
||||
if (!empty($sessionData['courses'])) {
|
||||
$sessionId = $sessionData['session_id'];
|
||||
foreach ($sessionData['courses'] as $courseData) {
|
||||
$cats = Category::load(
|
||||
null,
|
||||
null,
|
||||
$courseData['course_code'],
|
||||
null,
|
||||
null,
|
||||
$sessionId,
|
||||
false
|
||||
);
|
||||
|
||||
if (isset($cats[0]) && !empty($cats[0])) {
|
||||
Category::generateUserCertificate(
|
||||
$cats[0]->get_id(),
|
||||
$userId
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
162
main/inc/lib/chamilo_session.class.php
Normal file
162
main/inc/lib/chamilo_session.class.php
Normal file
@@ -0,0 +1,162 @@
|
||||
<?php
|
||||
|
||||
use Symfony\Component\HttpFoundation\Session\Session;
|
||||
|
||||
/**
|
||||
* Chamilo session (i.e. the session that maintains the connection open after usr login).
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
*
|
||||
* use ChamiloSession as Session;
|
||||
*
|
||||
* Session::read('name');
|
||||
*
|
||||
* Or
|
||||
*
|
||||
* Chamilo::session()->...
|
||||
* session()->...
|
||||
*
|
||||
* @license see /license.txt
|
||||
* @author Laurent Opprecht <laurent@opprecht.info> for the Univesity of Geneva
|
||||
*/
|
||||
/**
|
||||
* @todo use session symfony component
|
||||
* @todo replace all $_SESSION calls with this class.
|
||||
* @todo remove System\Session class
|
||||
* ChamiloSession class definition
|
||||
*/
|
||||
class ChamiloSession extends System\Session
|
||||
{
|
||||
public const NAME = 'ch_sid';
|
||||
|
||||
/**
|
||||
* Generate new session instance.
|
||||
*
|
||||
* @return ChamiloSession
|
||||
*/
|
||||
public static function instance()
|
||||
{
|
||||
static $result = null;
|
||||
if (empty($result)) {
|
||||
$result = new ChamiloSession();
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the session lifetime.
|
||||
*
|
||||
* @return int The session lifetime as defined in the config file, in seconds
|
||||
*/
|
||||
public static function session_lifetime()
|
||||
{
|
||||
return api_get_configuration_value('session_lifetime');
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the Chamilo session.
|
||||
*
|
||||
* The default lifetime for session is set here. It is not possible to have it
|
||||
* as a database setting as it is used before the database connection has been made.
|
||||
* It is taken from the configuration file, and if it doesn't exist there, it is set
|
||||
* to 360000 seconds
|
||||
*
|
||||
* @author Olivier Brouckaert
|
||||
*
|
||||
* @param string variable - the variable name to save into the session
|
||||
*/
|
||||
public static function start($already_installed = true)
|
||||
{
|
||||
/*
|
||||
* Prevent Session fixation bug fixes
|
||||
* See http://support.chamilo.org/issues/3600
|
||||
* http://php.net/manual/en/session.configuration.php
|
||||
* @todo use session_set_cookie_params with some custom admin parameters
|
||||
*/
|
||||
|
||||
//session.cookie_lifetime
|
||||
//the session ID is only accepted from a cookie
|
||||
ini_set('session.use_only_cookies', 1);
|
||||
|
||||
//HTTPS only if possible
|
||||
//ini_set('session.cookie_secure', 1);
|
||||
//session ID in the cookie is only readable by the server
|
||||
ini_set('session.cookie_httponly', 1);
|
||||
if (api_is_https()) {
|
||||
ini_set('session.cookie_secure', 1);
|
||||
}
|
||||
|
||||
if (api_get_configuration_value('security_session_cookie_samesite_none')) {
|
||||
if (PHP_VERSION_ID < 70300) {
|
||||
$sessionCookieParams = session_get_cookie_params();
|
||||
session_set_cookie_params($sessionCookieParams['lifetime'], '/; samesite=None',
|
||||
$sessionCookieParams['domain'], true, $sessionCookieParams['httponly']);
|
||||
} else {
|
||||
ini_set('session.cookie_samesite', 'None');
|
||||
}
|
||||
}
|
||||
|
||||
//Use entropy file
|
||||
//session.entropy_file
|
||||
//ini_set('session.entropy_length', 128);
|
||||
//Do not include the identifier in the URL, and not to read the URL for
|
||||
// identifiers.
|
||||
ini_set('session.use_trans_sid', 0);
|
||||
|
||||
session_name(self::NAME);
|
||||
session_start();
|
||||
$session = self::instance();
|
||||
if ($already_installed) {
|
||||
if (!isset($session['checkChamiloURL'])) {
|
||||
$session['checkChamiloURL'] = api_get_path(WEB_PATH);
|
||||
} elseif ($session['checkChamiloURL'] != api_get_path(WEB_PATH)) {
|
||||
self::clear();
|
||||
}
|
||||
}
|
||||
|
||||
// If the session time has expired, refresh the starttime value,
|
||||
// so we're starting to count down from a later time
|
||||
if (self::has('starttime') && $session->is_expired()) {
|
||||
self::destroy();
|
||||
} else {
|
||||
//error_log('Time not expired, extend session for a bit more');
|
||||
self::write('starttime', time());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Session start time: that is the last time the user loaded a page (before this time).
|
||||
*
|
||||
* @return int timestamp
|
||||
*/
|
||||
public function start_time()
|
||||
{
|
||||
return self::read('starttime');
|
||||
}
|
||||
|
||||
/**
|
||||
* Session end time: when the session expires. This is made of the last page
|
||||
* load time + a number of seconds.
|
||||
*
|
||||
* @return int UNIX timestamp (server's timezone)
|
||||
*/
|
||||
public function end_time()
|
||||
{
|
||||
$start_time = $this->start_time();
|
||||
$lifetime = self::session_lifetime();
|
||||
|
||||
return $start_time + $lifetime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the session is expired.
|
||||
*
|
||||
* @return bool True if the session is expired, false if it is still valid
|
||||
*/
|
||||
public function is_expired()
|
||||
{
|
||||
return $this->end_time() < time();
|
||||
}
|
||||
}
|
||||
530
main/inc/lib/chat.lib.php
Normal file
530
main/inc/lib/chat.lib.php
Normal file
@@ -0,0 +1,530 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use ChamiloSession as Session;
|
||||
|
||||
/**
|
||||
* Class Chat.
|
||||
*
|
||||
* @todo ChamiloSession instead of $_SESSION
|
||||
*/
|
||||
class Chat extends Model
|
||||
{
|
||||
public $columns = [
|
||||
'id',
|
||||
'from_user',
|
||||
'to_user',
|
||||
'message',
|
||||
'sent',
|
||||
'recd',
|
||||
];
|
||||
public $window_list = [];
|
||||
|
||||
/**
|
||||
* The contructor sets the chat table name and the window_list attribute.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->table = Database::get_main_table(TABLE_MAIN_CHAT);
|
||||
$this->window_list = Session::read('window_list');
|
||||
Session::write('window_list', $this->window_list);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user chat status.
|
||||
*
|
||||
* @return int 0 if disconnected, 1 if connected
|
||||
*/
|
||||
public function getUserStatus()
|
||||
{
|
||||
$status = UserManager::get_extra_user_data_by_field(
|
||||
api_get_user_id(),
|
||||
'user_chat_status',
|
||||
false,
|
||||
true
|
||||
);
|
||||
|
||||
return $status['user_chat_status'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set user chat status.
|
||||
*
|
||||
* @param int $status 0 if disconnected, 1 if connected
|
||||
*/
|
||||
public function setUserStatus($status)
|
||||
{
|
||||
UserManager::update_extra_field_value(
|
||||
api_get_user_id(),
|
||||
'user_chat_status',
|
||||
$status
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $currentUserId
|
||||
* @param int $userId
|
||||
* @param bool $latestMessages
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getLatestChat($currentUserId, $userId, $latestMessages)
|
||||
{
|
||||
$items = $this->getPreviousMessages(
|
||||
$currentUserId,
|
||||
$userId,
|
||||
0,
|
||||
$latestMessages
|
||||
);
|
||||
|
||||
return array_reverse($items);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getContacts()
|
||||
{
|
||||
$html = SocialManager::listMyFriendsBlock(
|
||||
api_get_user_id(),
|
||||
'',
|
||||
true
|
||||
);
|
||||
|
||||
echo $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $chatHistory
|
||||
* @param int $latestMessages
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getAllLatestChats($chatHistory, $latestMessages = 5)
|
||||
{
|
||||
$currentUserId = api_get_user_id();
|
||||
|
||||
if (empty($chatHistory)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$chats = [];
|
||||
foreach ($chatHistory as $userId => $time) {
|
||||
$total = $this->getCountMessagesExchangeBetweenUsers($userId, $currentUserId);
|
||||
$start = $total - $latestMessages;
|
||||
if ($start < 0) {
|
||||
$start = 0;
|
||||
}
|
||||
$items = $this->getMessages($userId, $currentUserId, $start, $latestMessages);
|
||||
$chats[$userId]['items'] = $items;
|
||||
$chats[$userId]['window_user_info'] = api_get_user_info($userId);
|
||||
}
|
||||
|
||||
return $chats;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a chat session and returns JSON array of status and chat history.
|
||||
*
|
||||
* @return bool (prints output in JSON format)
|
||||
*/
|
||||
public function startSession()
|
||||
{
|
||||
// ofaj
|
||||
// $chat = new Chat();
|
||||
// $chat->setUserStatus(1);
|
||||
|
||||
$chatList = Session::read('openChatBoxes');
|
||||
$chats = $this->getAllLatestChats($chatList);
|
||||
$return = [
|
||||
'user_status' => $this->getUserStatus(),
|
||||
'me' => get_lang('Me'),
|
||||
'user_id' => api_get_user_id(),
|
||||
'items' => $chats,
|
||||
'sec_token' => Security::get_token('chat'),
|
||||
];
|
||||
echo json_encode($return);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $fromUserId
|
||||
* @param int $toUserId
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getCountMessagesExchangeBetweenUsers($fromUserId, $toUserId)
|
||||
{
|
||||
$row = Database::select(
|
||||
'count(*) as count',
|
||||
$this->table,
|
||||
[
|
||||
'where' => [
|
||||
'(from_user = ? AND to_user = ?) OR (from_user = ? AND to_user = ?) ' => [
|
||||
$fromUserId,
|
||||
$toUserId,
|
||||
$toUserId,
|
||||
$fromUserId,
|
||||
],
|
||||
],
|
||||
],
|
||||
'first'
|
||||
);
|
||||
|
||||
return (int) $row['count'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $fromUserId
|
||||
* @param int $toUserId
|
||||
* @param int $visibleMessages
|
||||
* @param int $previousMessageCount messages to show
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getPreviousMessages(
|
||||
$fromUserId,
|
||||
$toUserId,
|
||||
$visibleMessages = 1,
|
||||
$previousMessageCount = 5,
|
||||
$orderBy = ''
|
||||
) {
|
||||
$toUserId = (int) $toUserId;
|
||||
$fromUserId = (int) $fromUserId;
|
||||
$visibleMessages = (int) $visibleMessages;
|
||||
$previousMessageCount = (int) $previousMessageCount;
|
||||
|
||||
$total = $this->getCountMessagesExchangeBetweenUsers($fromUserId, $toUserId);
|
||||
$show = $total - $visibleMessages;
|
||||
|
||||
if ($show < $previousMessageCount) {
|
||||
$show = $previousMessageCount;
|
||||
}
|
||||
$from = $show - $previousMessageCount;
|
||||
|
||||
if ($from < 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $this->getMessages($fromUserId, $toUserId, $from, $previousMessageCount, $orderBy);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $fromUserId
|
||||
* @param int $toUserId
|
||||
* @param int $start
|
||||
* @param int $end
|
||||
* @param string $orderBy
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMessages($fromUserId, $toUserId, $start, $end, $orderBy = '')
|
||||
{
|
||||
$toUserId = (int) $toUserId;
|
||||
$fromUserId = (int) $fromUserId;
|
||||
$start = (int) $start;
|
||||
$end = (int) $end;
|
||||
|
||||
if (empty($toUserId) || empty($fromUserId)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$orderBy = Database::escape_string($orderBy);
|
||||
if (empty($orderBy)) {
|
||||
$orderBy = 'ORDER BY id ASC';
|
||||
}
|
||||
|
||||
$sql = "SELECT * FROM ".$this->table."
|
||||
WHERE
|
||||
(
|
||||
to_user = $toUserId AND
|
||||
from_user = $fromUserId
|
||||
)
|
||||
OR
|
||||
(
|
||||
from_user = $toUserId AND
|
||||
to_user = $fromUserId
|
||||
)
|
||||
$orderBy
|
||||
LIMIT $start, $end
|
||||
";
|
||||
$result = Database::query($sql);
|
||||
$rows = Database::store_result($result);
|
||||
$fromUserInfo = api_get_user_info($fromUserId, true);
|
||||
$toUserInfo = api_get_user_info($toUserId, true);
|
||||
$users = [
|
||||
$fromUserId => $fromUserInfo,
|
||||
$toUserId => $toUserInfo,
|
||||
];
|
||||
$items = [];
|
||||
$rows = array_reverse($rows);
|
||||
foreach ($rows as $chat) {
|
||||
$fromUserId = $chat['from_user'];
|
||||
$userInfo = $users[$fromUserId];
|
||||
$toUserInfo = $users[$toUserId];
|
||||
|
||||
$items[$chat['id']] = [
|
||||
'id' => $chat['id'],
|
||||
'message' => Security::remove_XSS($chat['message']),
|
||||
'date' => api_strtotime($chat['sent'], 'UTC'),
|
||||
'recd' => $chat['recd'],
|
||||
'from_user_info' => $userInfo,
|
||||
'to_user_info' => $toUserInfo,
|
||||
];
|
||||
$_SESSION['openChatBoxes'][$fromUserId] = api_strtotime($chat['sent'], 'UTC');
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshes the chat windows (usually called every x seconds through AJAX).
|
||||
*/
|
||||
public function heartbeat()
|
||||
{
|
||||
$chatHistory = Session::read('chatHistory');
|
||||
$currentUserId = api_get_user_id();
|
||||
|
||||
// update current chats
|
||||
if (!empty($chatHistory) && is_array($chatHistory)) {
|
||||
foreach ($chatHistory as $fromUserId => &$data) {
|
||||
$userInfo = api_get_user_info($fromUserId, true);
|
||||
$count = $this->getCountMessagesExchangeBetweenUsers($fromUserId, $currentUserId);
|
||||
$chatItems = $this->getLatestChat($fromUserId, $currentUserId, 5);
|
||||
$data['window_user_info'] = $userInfo;
|
||||
$data['items'] = $chatItems;
|
||||
$data['total_messages'] = $count;
|
||||
}
|
||||
}
|
||||
|
||||
$sql = "SELECT * FROM ".$this->table."
|
||||
WHERE
|
||||
to_user = '".$currentUserId."' AND recd = 0
|
||||
ORDER BY id ASC";
|
||||
$result = Database::query($sql);
|
||||
|
||||
$chatList = [];
|
||||
while ($chat = Database::fetch_array($result, 'ASSOC')) {
|
||||
$chatList[$chat['from_user']][] = $chat;
|
||||
}
|
||||
|
||||
foreach ($chatList as $fromUserId => $messages) {
|
||||
$userInfo = api_get_user_info($fromUserId, true);
|
||||
$count = $this->getCountMessagesExchangeBetweenUsers($fromUserId, $currentUserId);
|
||||
$chatItems = $this->getLatestChat($fromUserId, $currentUserId, 5);
|
||||
|
||||
// Cleaning tsChatBoxes
|
||||
unset($_SESSION['tsChatBoxes'][$fromUserId]);
|
||||
|
||||
foreach ($messages as $chat) {
|
||||
$_SESSION['openChatBoxes'][$fromUserId] = api_strtotime($chat['sent'], 'UTC');
|
||||
}
|
||||
|
||||
$chatHistory[$fromUserId] = [
|
||||
'window_user_info' => $userInfo,
|
||||
'total_messages' => $count,
|
||||
'items' => $chatItems,
|
||||
];
|
||||
}
|
||||
|
||||
Session::write('chatHistory', $chatHistory);
|
||||
|
||||
$sql = "UPDATE ".$this->table."
|
||||
SET recd = 1
|
||||
WHERE to_user = $currentUserId AND recd = 0";
|
||||
Database::query($sql);
|
||||
|
||||
echo json_encode(['items' => $chatHistory]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves into session the fact that a chat window exists with the given user.
|
||||
*
|
||||
* @param int $userId
|
||||
*/
|
||||
public function saveWindow($userId)
|
||||
{
|
||||
$this->window_list[$userId] = true;
|
||||
Session::write('window_list', $this->window_list);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a message from one user to another user.
|
||||
*
|
||||
* @param int $fromUserId The ID of the user sending the message
|
||||
* @param int $to_user_id The ID of the user receiving the message
|
||||
* @param string $message Message
|
||||
* @param bool $printResult Optional. Whether print the result
|
||||
* @param bool $sanitize Optional. Whether sanitize the message
|
||||
*/
|
||||
public function send(
|
||||
$fromUserId,
|
||||
$to_user_id,
|
||||
$message,
|
||||
$printResult = true,
|
||||
$sanitize = true
|
||||
) {
|
||||
$relation = SocialManager::get_relation_between_contacts($fromUserId, $to_user_id);
|
||||
|
||||
if (!Security::check_token('post', null, 'chat')) {
|
||||
if ($printResult) {
|
||||
echo '0';
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
if (USER_RELATION_TYPE_FRIEND == $relation) {
|
||||
$now = api_get_utc_datetime();
|
||||
$user_info = api_get_user_info($to_user_id, true);
|
||||
$this->saveWindow($to_user_id);
|
||||
$_SESSION['openChatBoxes'][$to_user_id] = api_strtotime($now, 'UTC');
|
||||
|
||||
if ($sanitize) {
|
||||
$messagesan = $this->sanitize($message);
|
||||
} else {
|
||||
$messagesan = $message;
|
||||
}
|
||||
|
||||
if (!isset($_SESSION['chatHistory'][$to_user_id])) {
|
||||
$_SESSION['chatHistory'][$to_user_id] = [];
|
||||
}
|
||||
$item = [
|
||||
's' => '1',
|
||||
'f' => $fromUserId,
|
||||
'm' => $messagesan,
|
||||
'date' => api_strtotime($now, 'UTC'),
|
||||
'username' => get_lang('Me'),
|
||||
];
|
||||
$_SESSION['chatHistory'][$to_user_id]['items'][] = $item;
|
||||
$_SESSION['chatHistory'][$to_user_id]['user_info']['user_name'] = $user_info['complete_name'];
|
||||
$_SESSION['chatHistory'][$to_user_id]['user_info']['online'] = $user_info['user_is_online'];
|
||||
$_SESSION['chatHistory'][$to_user_id]['user_info']['avatar'] = $user_info['avatar_small'];
|
||||
$_SESSION['chatHistory'][$to_user_id]['user_info']['user_id'] = $user_info['user_id'];
|
||||
|
||||
unset($_SESSION['tsChatBoxes'][$to_user_id]);
|
||||
|
||||
$params = [];
|
||||
$params['from_user'] = (int) $fromUserId;
|
||||
$params['to_user'] = (int) $to_user_id;
|
||||
$params['message'] = $messagesan;
|
||||
$params['sent'] = api_get_utc_datetime();
|
||||
|
||||
if (!empty($fromUserId) && !empty($to_user_id)) {
|
||||
$messageId = $this->save($params);
|
||||
|
||||
if ($printResult) {
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode(['id' => $messageId, 'sec_token' => Security::get_token('chat')]);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($printResult) {
|
||||
echo '0';
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Close a specific chat box (user ID taken from $_POST['chatbox']).
|
||||
*
|
||||
* @param int $userId
|
||||
*/
|
||||
public function closeWindow($userId)
|
||||
{
|
||||
if (empty($userId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$list = Session::read('openChatBoxes');
|
||||
if (isset($list[$userId])) {
|
||||
unset($list[$userId]);
|
||||
Session::write('openChatBoxes', $list);
|
||||
}
|
||||
|
||||
$list = Session::read('chatHistory');
|
||||
if (isset($list[$userId])) {
|
||||
unset($list[$userId]);
|
||||
Session::write('chatHistory', $list);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close chat - disconnects the user.
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
Session::erase('tsChatBoxes');
|
||||
Session::erase('openChatBoxes');
|
||||
Session::erase('chatHistory');
|
||||
Session::erase('window_list');
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter chat messages to avoid XSS or other JS.
|
||||
*
|
||||
* @param string $text Unfiltered message
|
||||
*
|
||||
* @return string Filtered message
|
||||
*/
|
||||
public function sanitize($text)
|
||||
{
|
||||
$text = htmlspecialchars($text, ENT_QUOTES);
|
||||
$text = str_replace("\n\r", "\n", $text);
|
||||
$text = str_replace("\r\n", "\n", $text);
|
||||
$text = str_replace("\n", "<br>", $text);
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* SET Disable Chat.
|
||||
*
|
||||
* @param bool $status to disable chat
|
||||
*/
|
||||
public static function setDisableChat($status = true)
|
||||
{
|
||||
Session::write('disable_chat', $status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable Chat - disable the chat.
|
||||
*
|
||||
* @return bool - return true if setDisableChat status is true
|
||||
*/
|
||||
public static function disableChat()
|
||||
{
|
||||
$status = Session::read('disable_chat');
|
||||
if (!empty($status)) {
|
||||
if ($status == true) {
|
||||
Session::write('disable_chat', null);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isChatBlockedByExercises()
|
||||
{
|
||||
$currentExercises = Session::read('current_exercises');
|
||||
if (!empty($currentExercises)) {
|
||||
foreach ($currentExercises as $attempt_status) {
|
||||
if ($attempt_status == true) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
44
main/inc/lib/conditional_login.class.php
Normal file
44
main/inc/lib/conditional_login.class.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Conditional login
|
||||
* Used to implement the loading of custom pages
|
||||
* 2011, Noel Dieschburg <noel@cblue.be>.
|
||||
*/
|
||||
class ConditionalLogin
|
||||
{
|
||||
/**
|
||||
* Check conditions based in the $login_conditions see conditional_login.php file.
|
||||
*
|
||||
* @param array $user
|
||||
*/
|
||||
public static function check_conditions($user)
|
||||
{
|
||||
$file = api_get_path(SYS_CODE_PATH).'auth/conditional_login/conditional_login.php';
|
||||
if (file_exists($file)) {
|
||||
include_once $file;
|
||||
if (isset($login_conditions)) {
|
||||
foreach ($login_conditions as $condition) {
|
||||
//If condition fails we redirect to the URL defined by the condition
|
||||
if (isset($condition['conditional_function'])) {
|
||||
$function = $condition['conditional_function'];
|
||||
$result = $function($user);
|
||||
if (false == $result) {
|
||||
$_SESSION['conditional_login']['uid'] = $user['user_id'];
|
||||
$_SESSION['conditional_login']['can_login'] = false;
|
||||
header("Location: ".$condition['url']);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function login()
|
||||
{
|
||||
$_SESSION['conditional_login']['can_login'] = true;
|
||||
LoginRedirection::redirect();
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user