Actualización
This commit is contained in:
@@ -0,0 +1 @@
|
||||
Options -Indexes
|
||||
Binary file not shown.
@@ -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();
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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();
|
||||
@@ -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;
|
||||
@@ -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();
|
||||
@@ -0,0 +1,287 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
/**
|
||||
* Responses to AJAX calls for the document upload.
|
||||
*/
|
||||
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 $file) {
|
||||
if (isset($_REQUEST['chunkAction']) && 'done' === $_REQUEST['chunkAction']) {
|
||||
// to rename and move the finished file
|
||||
$tmpFile = disable_dangerous_file(
|
||||
api_replace_dangerous_char($file['name'])
|
||||
);
|
||||
$chunkedFile = api_get_path(SYS_ARCHIVE_PATH).$tmpFile;
|
||||
$file['tmp_name'] = $chunkedFile;
|
||||
$file['size'] = filesize($chunkedFile);
|
||||
$file['copy_file'] = true;
|
||||
}
|
||||
|
||||
$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':
|
||||
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'];
|
||||
$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) {
|
||||
$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;
|
||||
}
|
||||
if (move_uploaded_file($fileUpload['tmp_name'], $syspath.$fileUploadName)) {
|
||||
$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;
|
||||
@@ -0,0 +1,126 @@
|
||||
<?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 $file) {
|
||||
if (isset($_REQUEST['chunkAction']) && 'done' === $_REQUEST['chunkAction']) {
|
||||
// to rename and move the finished file
|
||||
$chunkedFile = api_get_path(SYS_ARCHIVE_PATH).$file['name'];
|
||||
$file['tmp_name'] = $chunkedFile;
|
||||
$file['size'] = filesize($chunkedFile);
|
||||
$file['copy_file'] = true;
|
||||
}
|
||||
|
||||
$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;
|
||||
@@ -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;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -0,0 +1,6 @@
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
@@ -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;
|
||||
@@ -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 = 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
|
||||
// Replace double quotes to avoid parse errors
|
||||
$newLanguage = str_replace('"', '\"', $newLanguage);
|
||||
$newLanguage = str_replace("\n", "\\n", $newLanguage);
|
||||
$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;
|
||||
@@ -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;
|
||||
@@ -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 '';
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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();
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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']);
|
||||
}
|
||||
@@ -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;
|
||||
@@ -0,0 +1,440 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use Chamilo\CoreBundle\Entity\Message;
|
||||
use Chamilo\CoreBundle\Entity\MessageFeedback;
|
||||
use ChamiloSession as Session;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
$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 = $_GET['friend_id'];
|
||||
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;
|
||||
}
|
||||
break;
|
||||
case 'deny_friend':
|
||||
if (api_is_anonymous()) {
|
||||
echo '';
|
||||
break;
|
||||
}
|
||||
$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;
|
||||
}
|
||||
break;
|
||||
case 'delete_friend':
|
||||
if (api_is_anonymous()) {
|
||||
echo '';
|
||||
break;
|
||||
}
|
||||
$my_delete_friend = (int) $_POST['delete_friend_id'];
|
||||
if (isset($_POST['delete_friend_id'])) {
|
||||
SocialManager::remove_user_rel_user($my_delete_friend);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
$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);
|
||||
echo SocialManager::processPostComment($messageInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1,469 @@
|
||||
<?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;
|
||||
default:
|
||||
echo '';
|
||||
}
|
||||
exit;
|
||||
@@ -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;
|
||||
@@ -0,0 +1,259 @@
|
||||
<?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 $file) {
|
||||
if (isset($_REQUEST['chunkAction']) && 'done' === $_REQUEST['chunkAction']) {
|
||||
// to rename and move the finished file
|
||||
$chunkedFile = api_get_path(SYS_ARCHIVE_PATH).$file['name'];
|
||||
$file['tmp_name'] = $chunkedFile;
|
||||
$file['size'] = filesize($chunkedFile);
|
||||
$file['copy_file'] = true;
|
||||
}
|
||||
|
||||
$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;
|
||||
@@ -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();
|
||||
@@ -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();
|
||||
@@ -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"]);
|
||||
}
|
||||
@@ -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.'
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
@@ -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");
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
Options -Indexes
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,390 @@
|
||||
<?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'],
|
||||
];
|
||||
|
||||
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,
|
||||
'recipe_name' => 'anasim',
|
||||
],
|
||||
]
|
||||
)
|
||||
->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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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'];
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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]
|
||||
);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,517 @@
|
||||
<?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'));
|
||||
$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');
|
||||
}
|
||||
|
||||
$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';
|
||||
} else {
|
||||
document.getElementById('options').style.display = 'none';
|
||||
document.getElementById('specific_date').style.display = 'block';
|
||||
}
|
||||
", ]
|
||||
);
|
||||
|
||||
$form->addHtml('<div id="specific_date">');
|
||||
$form->addDateTimePicker('date', get_lang('Date'));
|
||||
$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);
|
||||
}
|
||||
|
||||
$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 (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
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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']);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,123 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use Brumann\Polyfill\Unserialize;
|
||||
|
||||
/**
|
||||
* 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::unserialize(
|
||||
$serialized,
|
||||
['allowed_classes' => $allowedClasses]
|
||||
);
|
||||
}
|
||||
|
||||
return Unserialize::unserialize(
|
||||
$serialized,
|
||||
['allowed_classes' => $allowedClasses]
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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