This commit is contained in:
Xes
2025-08-14 22:37:50 +02:00
parent fb6d5d5926
commit 3641e93527
9156 changed files with 1813532 additions and 0 deletions

429
main/calendar/agenda.php Normal file
View File

@@ -0,0 +1,429 @@
<?php
/* For licensing terms, see /license.txt */
// use anonymous mode when accessing this course tool
$use_anonymous = true;
require_once __DIR__.'/../inc/global.inc.php';
$current_course_tool = TOOL_CALENDAR_EVENT;
$course_info = api_get_course_info();
if (!empty($course_info)) {
api_protect_course_script(true);
}
$action = isset($_GET['action']) ? Security::remove_XSS($_GET['action']) : null;
$group_id = api_get_group_id();
$url = null;
if (empty($action)) {
if (!empty($course_info)) {
if (!empty($group_id)) {
$url = api_get_path(WEB_CODE_PATH).'calendar/agenda_js.php?type=course&'.api_get_cidreq().'&user_id=GROUP:'.$group_id;
} else {
$url = api_get_path(WEB_CODE_PATH).'calendar/agenda_js.php?type=course&'.api_get_cidreq();
}
} else {
$url = api_get_path(WEB_CODE_PATH).'calendar/agenda_js.php?';
}
header("Location: $url");
exit;
}
$logInfo = [
'tool' => TOOL_CALENDAR_EVENT,
'action' => $action,
];
Event::registerLog($logInfo);
$groupInfo = GroupManager::get_group_properties($group_id);
$eventId = $_REQUEST['id'] ?? null;
$type = $event_type = $_GET['type'] ?? null;
$messageId = (int) ($_REQUEST['m'] ?? 0);
$messageInfo = [];
$currentUserId = api_get_user_id();
if ($messageId) {
$event_type = 'personal';
$messageInfo = MessageManager::get_message_by_id($messageId);
if (!in_array($currentUserId, [$messageInfo['user_receiver_id'], $messageInfo['user_sender_id']])) {
api_not_allowed(true);
}
}
$htmlHeadXtra[] = "<script>
function plus_repeated_event() {
if (document.getElementById('options2').style.display === 'none') {
document.getElementById('options2').style.display = 'block';
} else {
document.getElementById('options2').style.display = 'none';
}
}
$(function() {
var checked = $('input[name=repeat]').attr('checked');
if (checked) {
$('#options2').show();
}
});
</script>";
$htmlHeadXtra[] = '<script>
var counter_image = 1;
function add_image_form() {
// Multiple filepaths for image form
var filepaths = document.getElementById("filepaths");
if (document.getElementById("filepath_"+counter_image)) {
counter_image = counter_image + 1;
} else {
counter_image = counter_image;
}
var elem1 = document.createElement("div");
elem1.setAttribute("id","filepath_"+counter_image);
filepaths.appendChild(elem1);
id_elem1 = "filepath_"+counter_image;
id_elem1 = "\'"+id_elem1+"\'";
document.getElementById("filepath_"+counter_image).innerHTML = "<input type=\"file\" name=\"attach_"+counter_image+"\" /><label>'.get_lang('Description').'</label><input class=\"form-control\" type=\"text\" name=\"legend[]\" />";
if (filepaths.childNodes.length == 6) {
var link_attach = document.getElementById("link-more-attach");
if (link_attach) {
link_attach.innerHTML="";
}
}
}
</script>';
$agendaRemindersEnabled = api_get_configuration_value('agenda_reminders');
if ($agendaRemindersEnabled) {
$htmlHeadXtra[] = '<script>$(function () {'
.Agenda::getJsForReminders('#add_event_add_notification')
.'});</script>'
;
}
// setting the name of the tool
$nameTools = get_lang('Agenda');
Event::event_access_tool(TOOL_CALENDAR_EVENT);
if ('fromjs' === $type) {
// split the "id" parameter only if string and there are _ separators
if (preg_match('/_/', $eventId)) {
$id_list = explode('_', $eventId);
} else {
$id_list = $eventId;
}
$eventId = $id_list[1];
$event_type = $id_list[0];
$event_type = 'platform' === $event_type ? 'admin' : $event_type;
}
$agenda = new Agenda($event_type);
$allowToEdit = $agenda->getIsAllowedToEdit();
$actions = $agenda->displayActions('calendar');
if (!$allowToEdit && 'course' === $event_type) {
api_not_allowed(true);
}
if ('course' === $event_type) {
$agendaUrl = api_get_path(WEB_CODE_PATH).'calendar/agenda_js.php?'.api_get_cidreq().'&type=course';
} else {
$agendaUrl = api_get_path(WEB_CODE_PATH).'calendar/agenda_js.php?&type='.$event_type;
if ($messageInfo) {
$agendaUrl = api_get_path(WEB_CODE_PATH).'messages/view_message.php?'
.http_build_query(
[
'type' => $messageInfo['msg_status'] === MESSAGE_STATUS_OUTBOX ? 2 : 1,
'id' => $messageInfo['id'],
]
);
}
}
$course_info = api_get_course_info();
$this_section = $course_info ? SECTION_COURSES : SECTION_MYAGENDA;
$em = Database::getManager();
$content = null;
if ($allowToEdit) {
switch ($action) {
case 'add':
$actionName = get_lang('Add');
$form = $agenda->getForm(['action' => 'add']);
if ($messageInfo) {
$form->addHidden('m', $messageInfo['id']);
}
if ($form->validate()) {
$values = $form->getSubmitValues();
$addAsAnnouncement = isset($values['add_announcement']);
$allDay = isset($values['all_day']) ? 'true' : 'false';
$sendAttachment = isset($_FILES) && !empty($_FILES);
$attachmentList = $sendAttachment ? $_FILES : null;
$attachmentCommentList = $values['legend'] ?? null;
$comment = $values['comment'] ?? null;
$usersToSend = $values['users_to_send'] ?? '';
$startDate = $values['date_range_start'];
$endDate = $values['date_range_end'];
$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(
$startDate,
$endDate,
$allDay,
$values['title'],
$values['content'],
$usersToSend,
$addAsAnnouncement,
null,
$attachmentList,
$attachmentCommentList,
$comment,
'',
$values['invitees'] ?? [],
$values['collective'] ?? false,
$reminders,
(int) $careerId,
(int) $promotionId,
$subscriptionVisibility,
$subscriptionItemId,
$maxSubscriptions
);
if (!empty($values['repeat']) && !empty($eventId)) {
// End date is always set as 23:59:59
$endDate = substr($values['repeat_end_day'], 0, 10).' 23:59:59';
$agenda->addRepeatedItem(
$eventId,
$values['repeat_type'],
$endDate,
$values['users_to_send']
);
}
$message = Display::return_message(get_lang('AddSuccess'), 'confirmation');
if ($addAsAnnouncement) {
$message .= Display::return_message(
get_lang('AdditionalMailWasSentToSelectedUsers'),
'confirmation'
);
}
Display::addFlash($message);
header("Location: $agendaUrl");
exit;
} else {
if (!empty($messageInfo)) {
MessageManager::setDefaultValuesInFormFromMessageInfo($messageInfo, $form);
}
$content = $form->returnForm();
}
break;
case 'edit':
$actionName = get_lang('Edit');
$event = $agenda->get_event((int) $eventId);
if (empty($event)) {
api_not_allowed(true);
}
$event['action'] = 'edit';
$event['id'] = $eventId;
$form = $agenda->getForm($event);
if ($form->validate()) {
$values = $form->getSubmitValues();
$allDay = isset($values['all_day']) ? 'true' : 'false';
$addAsAnnouncement = isset($values['add_announcement']);
$startDate = $values['date_range_start'];
$endDate = $values['date_range_end'];
$sendAttachment = isset($_FILES) && !empty($_FILES);
$attachmentList = $sendAttachment ? $_FILES : [];
$attachmentCommentList = $values['legend'] ?? '';
$comment = $values['comment'] ?? '';
$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);
$subscribers = $_REQUEST['subscribers'] ?? [];
$reminders = $notificationCount ? array_map(null, $notificationCount, $notificationPeriod) : [];
// This is a sub event. Delete the current and create another BT#7803
if (!empty($event['parent_event_id'])) {
$agenda->deleteEvent($eventId);
$eventId = $agenda->addEvent(
$startDate,
$endDate,
$allDay,
$values['title'],
$values['content'],
$values['users_to_send'],
false,
null,
$attachmentList,
$attachmentCommentList,
$comment,
'',
$values['invitees'] ?? [],
$values['collective'] ?? false,
$reminders
);
$message = Display::return_message(get_lang('Updated'), 'confirmation');
Display::addFlash($message);
header("Location: $agendaUrl");
exit;
}
$usersToSend = $values['users_to_send'] ?? '';
// Editing normal event.
$agenda->editEvent(
$eventId,
$startDate,
$endDate,
$allDay,
$values['title'],
$values['content'],
$usersToSend,
$attachmentList,
$attachmentCommentList,
$comment,
'',
$addAsAnnouncement,
true,
0,
$values['invitees'] ?? [],
$values['collective'] ?? false,
$reminders,
(int) $careerId,
(int) $promotionId,
$subscriptionVisibility,
$subscriptionItemId,
$maxSubscriptions,
$subscribers
);
if (!empty($values['repeat']) && !empty($eventId)) {
// End date is always set as 23:59:59
$endDate = substr($values['repeat_end_day'], 0, 10).' 23:59:59';
$agenda->addRepeatedItem(
$eventId,
$values['repeat_type'],
$endDate,
$values['users_to_send']
);
}
$deleteAttachmentList = $values['delete_attachment'] ?? [];
if (!empty($deleteAttachmentList)) {
foreach ($deleteAttachmentList as $deleteAttachmentId => $value) {
$agenda->deleteAttachmentFile(
$deleteAttachmentId,
$agenda->course
);
}
}
$message = Display::return_message(get_lang('Updated'), 'confirmation');
Display::addFlash($message);
header("Location: $agendaUrl");
exit;
} else {
$content = $form->returnForm();
}
break;
case 'importical':
$actionName = get_lang('Import');
$form = $agenda->getImportCalendarForm();
if ($form->validate()) {
$ical_name = $_FILES['ical_import']['name'];
$ical_type = $_FILES['ical_import']['type'];
$ext = substr($ical_name, (strrpos($ical_name, ".") + 1));
if (in_array($ext, ['ics', 'ical', 'icalendar', 'ifb'])) {
$content = $agenda->importEventFile($course_info, $_FILES['ical_import']);
$message = Display::return_message(get_lang('AddSuccess'));
} else {
$message = Display::return_message(get_lang('IsNotiCalFormatFile'), 'error');
}
Display::addFlash($message);
$url = api_get_self().'?action=importical&type='.$agenda->type;
header("Location: $url");
exit;
}
$content = $form->returnForm();
break;
case 'delete':
if (!(api_is_session_general_coach() &&
!api_is_element_in_the_session(TOOL_AGENDA, $eventId))
) {
// a coach can only delete an element belonging to his session
$content = $agenda->deleteEvent($eventId);
}
break;
case 'import_course_agenda_reminders':
if (!empty($course_info)) {
header('Location: '.api_get_path(WEB_CODE_PATH)
.'admin/import_course_agenda_reminders.php?'.api_get_cidreq().'&type=course'
);
exit();
}
}
}
if (!empty($group_id)) {
$group_properties = GroupManager::get_group_properties($group_id);
$interbreadcrumb[] = [
"url" => api_get_path(WEB_CODE_PATH)."group/group.php?".api_get_cidreq(),
"name" => get_lang('Groups'),
];
$interbreadcrumb[] = [
"url" => api_get_path(WEB_CODE_PATH)."group/group_space.php?".api_get_cidreq(),
"name" => get_lang('GroupSpace').' '.$group_properties['name'],
];
}
if (!empty($actionName)) {
$interbreadcrumb[] = [
"url" => $url,
"name" => get_lang('Agenda'),
];
} else {
$actionName = '';
}
// Tool introduction
$introduction = Display::return_introduction_section(TOOL_CALENDAR_EVENT);
$tpl = new Template($actionName);
$tpl->assign('content', $content);
$tpl->assign('actions', $actions);
$tpl->display_one_col_template();

408
main/calendar/agenda_js.php Normal file
View File

@@ -0,0 +1,408 @@
<?php
/* For licensing terms, see /license.txt */
// use anonymous mode when accessing this course tool
use Chamilo\CoreBundle\Entity\AgendaEventSubscription;
$use_anonymous = true;
$typeList = ['personal', 'course', 'admin', 'platform'];
// Calendar type
$type = isset($_REQUEST['type']) && in_array($_REQUEST['type'], $typeList) ? $_REQUEST['type'] : 'personal';
$userId = isset($_REQUEST['user_id']) ? $_REQUEST['user_id'] : null;
if ('personal' == $type || 'admin' == $type) {
$cidReset = true; // fixes #5162
}
require_once __DIR__.'/../inc/global.inc.php';
api_block_inactive_user();
$current_course_tool = TOOL_CALENDAR_EVENT;
$this_section = SECTION_MYAGENDA;
$htmlHeadXtra[] = api_get_jquery_libraries_js(['jquery-ui', 'jquery-ui-i18n']);
$htmlHeadXtra[] = api_get_asset('qtip2/jquery.qtip.min.js');
$htmlHeadXtra[] = api_get_asset('fullcalendar/dist/fullcalendar.js');
$htmlHeadXtra[] = api_get_asset('fullcalendar/dist/locale-all.js');
$htmlHeadXtra[] = api_get_asset('fullcalendar/dist/gcal.js');
$htmlHeadXtra[] = api_get_css_asset('fullcalendar/dist/fullcalendar.min.css');
$htmlHeadXtra[] = api_get_css_asset('qtip2/jquery.qtip.min.css');
if (api_is_platform_admin() && ($type == 'admin' || $type == 'platform')) {
$type = 'admin';
}
if (isset($_REQUEST['cidReq']) && !empty($_REQUEST['cidReq'])) {
if ($_REQUEST['cidReq'] == -1) {
// When is out of the course tool (e.g My agenda)
header('Location: '.api_get_self());
exit;
} else {
$type = 'course';
$this_section = SECTION_COURSES;
}
}
api_protect_course_group(GroupManager::GROUP_TOOL_CALENDAR);
$agenda = new Agenda($type);
$is_group_tutor = false;
$session_id = api_get_session_id();
$group_id = api_get_group_id();
$courseId = api_get_course_int_id();
if (!empty($group_id)) {
$group_properties = GroupManager::get_group_properties($group_id);
$is_group_tutor = GroupManager::is_tutor_of_group(
api_get_user_id(),
$group_properties,
$courseId
);
$interbreadcrumb[] = [
"url" => api_get_path(WEB_CODE_PATH)."group/group.php?".api_get_cidreq(),
"name" => get_lang('Groups'),
];
$interbreadcrumb[] = [
"url" => api_get_path(WEB_CODE_PATH)."group/group_space.php?".api_get_cidreq(),
"name" => get_lang('GroupSpace').' '.$group_properties['name'],
];
}
$tpl = new Template(get_lang('Agenda'));
$tpl->assign('use_google_calendar', 0);
$can_add_events = 0;
switch ($type) {
case 'admin':
api_protect_admin_script();
$this_section = SECTION_PLATFORM_ADMIN;
if (api_is_platform_admin()) {
$can_add_events = 1;
}
break;
case 'course':
api_protect_course_script(true);
$allowToEdit = $agenda->getIsAllowedToEdit();
$this_section = SECTION_COURSES;
if ($allowToEdit) {
$can_add_events = 1;
}
break;
case 'personal':
if (api_is_anonymous()) {
api_not_allowed(true);
}
$googleCalendarUrl = Agenda::returnGoogleCalendarUrl(api_get_user_id());
if (!empty($googleCalendarUrl)) {
$tpl->assign('use_google_calendar', 1);
$tpl->assign('google_calendar_url', $googleCalendarUrl);
}
$this_section = SECTION_MYAGENDA;
if (!api_is_anonymous() && ('true' === api_get_setting('allow_personal_agenda'))) {
$can_add_events = 1;
}
break;
}
$tpl->assign('js_format_date', 'll');
$region_value = api_get_language_isocode();
if ('en' == $region_value) {
$region_value = 'en-GB';
}
$tpl->assign('region_value', $region_value);
$export_icon = Display::return_icon(
'export.png',
null,
null,
null,
null,
true,
false
);
$export_icon_low = Display::return_icon(
'export_low_fade.png',
null,
null,
null,
null,
true,
false
);
$export_icon_high = Display::return_icon(
'export_high_fade.png',
null,
null,
null,
null,
true,
false
);
$tpl->assign(
'export_ical_confidential_icon',
Display::return_icon($export_icon_high, get_lang('ExportiCalConfidential'))
);
$actions = $agenda->displayActions('calendar', $userId);
$tpl->assign('toolbar', $actions);
// Calendar Type : course, admin, personal
$tpl->assign('type', $type);
$type_event_class = $type.'_event';
$type_label = get_lang(ucfirst($type).'Calendar');
if ($type == 'course' && !empty($group_id)) {
$type_event_class = 'group_event';
$type_label = get_lang('GroupCalendar');
}
$defaultView = api_get_setting('default_calendar_view');
if (empty($defaultView)) {
$defaultView = 'month';
}
/* month, basicWeek, agendaWeek, agendaDay */
$tpl->assign('default_view', $defaultView);
if ($type == 'course' && !empty($session_id)) {
$type_event_class = 'session_event';
$type_label = get_lang('SessionCalendar');
}
$agendaColors = array_merge(
[
'platform' => 'red', //red
'course' => '#458B00', //green
'group' => '#A0522D', //siena
'session' => '#00496D', // kind of green
'other_session' => '#999', // kind of green
'personal' => 'steel blue', //steel blue
'student_publication' => '#FF8C00', //DarkOrange
],
api_get_configuration_value('agenda_colors') ?: []
);
switch ($type_event_class) {
case 'admin_event':
$tpl->assign('type_event_color', $agendaColors['platform']);
break;
case 'course_event':
$tpl->assign('type_event_color', $agendaColors['course']);
break;
case 'group_event':
$tpl->assign('type_event_color', $agendaColors['group']);
break;
case 'session_event':
$tpl->assign('type_event_color', $agendaColors['session']);
break;
case 'personal_event':
$tpl->assign('type_event_color', $agendaColors['personal']);
break;
}
$tpl->assign('type_label', $type_label);
$tpl->assign('type_event_class', $type_event_class);
// Current user can add event?
$tpl->assign('can_add_events', $can_add_events);
// Setting AJAX caller
if (!empty($userId)) {
$agenda_ajax_url = api_get_path(WEB_AJAX_PATH).'agenda.ajax.php?user_id='.$userId.'&type='.$type;
} else {
$agenda_ajax_url = api_get_path(WEB_AJAX_PATH).'agenda.ajax.php?type='.$type;
}
if ('course' === $type && !empty($courseId)) {
$agenda_ajax_url .= '&'.api_get_cidreq();
}
if (isset($_GET['session_id'])) {
$agenda_ajax_url .= '&session_id='.intval($_GET['session_id']);
}
$agenda_ajax_url .= '&sec_token='.Security::get_token();
$tpl->assign('web_agenda_ajax_url', $agenda_ajax_url);
$form = new FormValidator(
'form',
'get',
api_get_self().'?'.api_get_cidreq(),
null,
['id' => 'add_event_form']
);
$form->addHeader(get_lang('Events'));
$form->addHtml('<span id="calendar_course_info"></span><div id="visible_to_input">');
$sendTo = $agenda->parseAgendaFilter($userId);
$addOnlyItemsInSendTo = true;
if ($sendTo['everyone']) {
$addOnlyItemsInSendTo = false;
}
$agenda->showToForm($form, $sendTo, [], $addOnlyItemsInSendTo);
$form->addHtml('</div>');
$form->addHtml('<div id="visible_to_read_only" style="display: none">');
$form->addElement('label', get_lang('To'), '<p id="visible_to_read_only_users" class="form-control-static"></p>');
$form->addHtml('</div>');
$form->addElement('label', get_lang('Agenda'), '<p class="form-control-static"><span id ="color_calendar"></span></p>');
$form->addElement(
'label',
get_lang('Date'), '<p class="form-control-static"><span id="start_date"></span><span id="end_date"></span></p>'
);
$form->addElement('text', 'title', get_lang('Title'), ['id' => 'title']);
$form->addHtmlEditor(
'content',
get_lang('Description'),
false,
false,
[
'ToolbarSet' => 'TestProposedAnswer',
'Height' => '120',
'id' => 'content',
]
);
if ('course' === $agenda->type) {
$form->addHtml('<div id="add_as_announcement_div" style="display: none">');
$form->addElement('checkbox', 'add_as_annonuncement', null, get_lang('AddAsAnnouncement'));
$form->addHtml('</div>');
$form->addElement('textarea', 'comment', get_lang('Comment'), ['id' => 'comment']);
}
$allowCollectiveInvitations = api_get_configuration_value('agenda_collective_invitations')
&& 'personal' === $agenda->type;
$allowEventSubscriptions = api_is_platform_admin()
&& api_get_configuration_value('agenda_event_subscriptions')
&& 'personal' === $agenda->type;
if ($allowCollectiveInvitations && $allowEventSubscriptions) {
$form->addRadio(
'invitation_type',
get_lang('Allowed'),
[
'invitations' => get_lang('Invitations'),
'subscriptions' => get_lang('Subscriptions'),
],
[
'onchange' => "$('#invitations-block, #subscriptions-block').hide(); $('#' + this.value + '-block').show();",
]
);
}
if ($allowCollectiveInvitations) {
$form->addHtml(
'<div id="invitations-block" style="display:'.($allowEventSubscriptions ? 'none;' : 'block;').'">'
);
$form->addHeader(get_lang('Invitations'));
$form->addSelectAjax(
'invitees',
get_lang('Invitees'),
[],
[
'multiple' => 'multiple',
'url' => api_get_path(WEB_AJAX_PATH).'message.ajax.php?a=find_users',
]
);
$form->addCheckBox('collective', '', get_lang('IsItEditableByTheInvitees'));
$form->addHtml('</div>');
}
if ($allowEventSubscriptions) {
$form->addHtml(
'<div id="subscriptions-block" style="display:'.($allowCollectiveInvitations ? 'none;' : 'block;').'">'
);
$form->addHeader(get_lang('Subscriptions'));
$form->addHtml('<div id="form_subscriptions_container" style="position: relative;">');
$form->addSelect(
'subscription_visibility',
get_lang('AllowSubscriptions'),
[
AgendaEventSubscription::SUBSCRIPTION_NO => get_lang('No'),
AgendaEventSubscription::SUBSCRIPTION_ALL => get_lang('AllUsersOfThePlatform'),
AgendaEventSubscription::SUBSCRIPTION_CLASS => get_lang('UsersInsideClass'),
],
[
'onchange' => 'document.getElementById(\'max_subscriptions\').disabled = this.value == 0; document.getElementById(\'form_subscription_item\').disabled = this.value != 2',
]
);
$form->addSelectAjax(
'subscription_item',
get_lang('SocialGroup').' / '.get_lang('Class'),
[],
[
'url' => api_get_path(WEB_AJAX_PATH).'usergroup.ajax.php?a=get_class_by_keyword',
'disabled' => 'disabled',
'dropdownParent' => '#form_subscriptions_container',
]
);
$form->addNumeric(
'max_subscriptions',
['', get_lang('MaxSubscriptionsLeaveEmptyToNotLimit')],
[
'disabled' => 'disabled',
'step' => 1,
'min' => 0,
'value' => 0,
]
);
$form->addHtml('</div>');
$form->addHtml('<div id="form_subscriptions_edit" style="display: none;"></div>');
$form->addHtml('</div>');
}
if (api_get_configuration_value('agenda_reminders')) {
$tpl->assign(
'agenda_reminders_js',
Agenda::getJsForReminders('#form_add_notification')
);
$form->addHtml('<hr><div id="notification_list"></div>');
$form->addButton('add_notification', get_lang('AddNotification'), 'bell-o')->setType('button');
$form->addHtml('<hr>');
}
if (api_get_configuration_value('allow_careers_in_global_agenda') && 'admin' === $agenda->type) {
Career::addCareerFieldsToForm($form);
$form->addHtml('<hr>');
}
$form->addHtml('<div id="attachment_block" style="display: none">');
$form->addHeader(get_lang('FilesAttachment'));
$form->addLabel(get_lang('Attachment'), '<div id="attachment_text" style="display: none"></div>');
$form->addHtml('</div>');
$tpl->assign('form_add', $form->returnForm());
$tpl->assign('legend_list', api_get_configuration_value('agenda_legend'));
$onHoverInfo = Agenda::returnOnHoverInfo();
$tpl->assign('on_hover_info', $onHoverInfo);
$extraSettings = Agenda::returnFullCalendarExtraSettings();
$tpl->assign('fullcalendar_settings', $extraSettings);
$tpl->assign('group_id', (!empty($group_id) ? $group_id : 0));
if (api_is_https()) {
$tpl->assign('is_https', 1);
} else {
$tpl->assign('is_https', 0);
}
$templateName = $tpl->get_template('agenda/month.tpl');
$content = $tpl->fetch($templateName);
$tpl->assign('content', $content);
$tpl->display_one_col_template();

View File

@@ -0,0 +1,112 @@
<?php
/* For licensing terms, see /license.txt */
require_once __DIR__.'/../inc/global.inc.php';
$action = isset($_GET['action']) ? Security::remove_XSS($_GET['action']) : 'calendar_list';
$logInfo = [
'tool' => TOOL_CALENDAR_EVENT,
'action' => $action,
];
Event::registerLog($logInfo);
$typeList = ['personal', 'course', 'admin', 'platform'];
$type = isset($_REQUEST['type']) && in_array($_REQUEST['type'], $typeList, true) ? $_REQUEST['type'] : null;
$interbreadcrumb[] = [
'url' => api_get_path(WEB_CODE_PATH).'calendar/agenda_js.php?type='.Security::remove_XSS($type),
'name' => get_lang('Agenda'),
];
$currentCourseId = api_get_course_int_id();
$groupId = api_get_group_id();
if (!empty($groupId)) {
$groupProperties = GroupManager::get_group_properties($groupId);
$groupId = $groupProperties['iid'];
$interbreadcrumb[] = [
'url' => api_get_path(WEB_CODE_PATH)."group/group.php?".api_get_cidreq(),
'name' => get_lang('Groups'),
];
$interbreadcrumb[] = [
'url' => api_get_path(WEB_CODE_PATH)."group/group_space.php?".api_get_cidreq(),
'name' => get_lang('GroupSpace').' '.$groupProperties['name'],
];
}
$agenda = new Agenda($type);
$events = $agenda->getEvents(
null,
null,
$currentCourseId,
$groupId,
null,
'array'
);
$this_section = SECTION_MYAGENDA;
if (!empty($currentCourseId) && $currentCourseId != -1) {
// Agenda is inside a course tool
$url = api_get_self().'?'.api_get_cidreq();
$this_section = SECTION_COURSES;
// Order by start date
usort($events, function ($a, $b) {
$t1 = strtotime($a['start']);
$t2 = strtotime($b['start']);
return $t1 > $t2;
});
} else {
// Agenda is out of the course tool (e.g personal agenda)
// Little hack to sort the events by start date in personal agenda (Agenda events List view - See #8014)
usort($events, function ($a, $b) {
$t1 = strtotime($a['start']);
$t2 = strtotime($b['start']);
return $t1 - $t2;
});
$url = false;
if (!empty($events)) {
foreach ($events as &$event) {
$courseId = isset($event['course_id']) ? $event['course_id'] : '';
$event['url'] = api_get_self().'?cid='.$courseId.'&type='.$event['type'];
}
}
}
$actions = $agenda->displayActions('list');
$tpl = new Template(get_lang('Events'));
$tpl->assign('agenda_events', $events);
$tpl->assign('url', $url);
$tpl->assign('show_action', in_array($type, ['course', 'session']));
$tpl->assign('agenda_actions', $actions);
$tpl->assign('is_allowed_to_edit', api_is_allowed_to_edit());
if (api_is_allowed_to_edit()) {
if ($action == 'change_visibility') {
$courseInfo = api_get_course_info();
$courseCondition = '';
// This happens when list agenda is not inside a course
if (($type == 'course' || $type == 'session' && !empty($courseInfo))) {
// For course and session event types
// Just needs course ID
$agenda->changeVisibility($_GET['id'], $_GET['visibility'], $courseInfo);
} else {
$courseCondition = '&'.api_get_cidreq();
}
header('Location: '.api_get_self().'?type='.$agenda->type.$courseCondition);
exit;
}
}
$templateName = $tpl->get_template('agenda/event_list.tpl');
$content = $tpl->fetch($templateName);
$tpl->assign('content', $content);
$tpl->display_one_col_template();

View File

@@ -0,0 +1,88 @@
<?php
/* For licensing terms, see /license.txt */
/**
* This file is responsible for passing requested documents to the browser.
* Html files are parsed to fix a few problems with URLs,
* but this code will hopefully be replaced soon by an Apache URL
* rewrite mechanism.
*
* @package chamilo.calendar
*/
session_cache_limiter('public');
require_once __DIR__.'/../inc/global.inc.php';
$this_section = SECTION_COURSES;
// IMPORTANT to avoid caching of documents
header('Expires: Wed, 01 Jan 1990 00:00:00 GMT');
header('Cache-Control: public');
header('Pragma: no-cache');
$course_id = isset($_REQUEST['course_id']) ? (int) $_REQUEST['course_id'] : api_get_course_int_id();
$user_id = api_get_user_id();
$course_info = api_get_course_info_by_id($course_id);
$doc_url = $_REQUEST['file'];
if (empty($course_id) || empty($doc_url)) {
api_not_allowed();
}
$session_id = api_get_session_id();
$is_user_is_subscribed = CourseManager::is_user_subscribed_in_course(
$user_id,
$course_info['code'],
true,
$session_id
);
if (!api_is_allowed_to_edit() && !$is_user_is_subscribed) {
api_not_allowed();
}
//change the '&' that got rewritten to '///' by mod_rewrite back to '&'
$doc_url = str_replace('///', '&', $doc_url);
//still a space present? it must be a '+' (that got replaced by mod_rewrite)
$doc_url = str_replace(' ', '+', $doc_url);
$doc_url = str_replace('/..', '', $doc_url); //echo $doc_url;
$full_file_name = api_get_path(SYS_COURSE_PATH).$course_info['path'].'/upload/calendar/'.$doc_url;
//if the rewrite rule asks for a directory, we redirect to the document explorer
if (is_dir($full_file_name)) {
while ($doc_url[$dul = strlen($doc_url) - 1] == '/') {
$doc_url = substr($doc_url, 0, $dul);
}
// create the path
$document_explorer = api_get_path(WEB_COURSE_PATH).$course_info['path']; // home course path
// redirect
header('Location: '.$document_explorer);
exit;
}
$tbl_agenda_attachment = Database::get_course_table(TABLE_AGENDA_ATTACHMENT);
// launch event
Event::event_download($doc_url);
$sql = 'SELECT filename FROM '.$tbl_agenda_attachment.'
WHERE
c_id = '.$course_id.' AND
path LIKE BINARY "'.Database::escape_string($doc_url).'"';
$result = Database::query($sql);
if (Database::num_rows($result)) {
$row = Database::fetch_array($result);
$title = str_replace(' ', '_', $row['filename']);
if (Security::check_abs_path(
$full_file_name,
api_get_path(SYS_COURSE_PATH).$course_info['path'].'/upload/calendar/'
)) {
$result = DocumentManager::file_send_for_download($full_file_name, true, $title);
if ($result === false) {
api_not_allowed(true);
}
}
}
api_not_allowed();

View File

@@ -0,0 +1,39 @@
<?php
/* For licensing terms, see /license.txt */
/**
* This file exclusively export event members for invitation or subscription.
*
* @author Nicolas Ducoulombier <nicolas.ducoulombier@beeznest.com>
*/
// setting the global file that gets the general configuration, the databases, the languages, ...
require_once __DIR__.'/../inc/global.inc.php';
$this_section = SECTION_MYAGENDA;
api_block_anonymous_users();
$type = 'personal';
$id = (int) explode('_', $_REQUEST['id'])[1];
$action = $_REQUEST['a'] ?? null;
if (empty($id)) {
exit;
}
$agenda = new Agenda($type);
switch ($action) {
case 'export_invitees':
if (!$agenda->getIsAllowedToEdit()) {
break;
}
$data = $agenda->exportEventMembersToCsv($id, "Invitee");
Export::arrayToCsv($data);
break;
case 'export_subscribers':
if (!$agenda->getIsAllowedToEdit()) {
break;
}
$data = $agenda->exportEventMembersToCsv($id, "Subscriber");
Export::arrayToCsv($data);
break;
}
exit;

View File

@@ -0,0 +1,169 @@
<?php
/* For licensing terms, see /license.txt */
use kigkonsult\iCalcreator\vcalendar;
use kigkonsult\iCalcreator\vevent;
/**
* This file exclusively export calendar items to iCal or similar formats.
*
* @author Yannick Warnier <yannick.warnier@beeznest.com>
*/
// we are not inside a course, so we reset the course id
$cidReset = true;
// setting the global file that gets the general configuration, the databases, the languages, ...
require_once __DIR__.'/../inc/global.inc.php';
$this_section = SECTION_MYAGENDA;
api_block_anonymous_users();
// setting the name of the tool
$nameTools = get_lang('MyAgenda');
// the variables for the days and the months
// Defining the shorts for the days
$DaysShort = api_get_week_days_short();
// Defining the days of the week to allow translation of the days
$DaysLong = api_get_week_days_long();
// Defining the months of the year to allow translation of the months
$MonthsLong = api_get_months_long();
if (empty($_GET['id'])) {
api_not_allowed();
}
$id = explode('_', $_GET['id']);
$type = $id[0];
$id = $id[1];
$agenda = new Agenda($type);
if (isset($_GET['course_id'])) {
$course_info = api_get_course_info_by_id($_GET['course_id']);
if (!empty($course_info)) {
$agenda->set_course($course_info);
}
}
$event = $agenda->get_event($id);
if (!empty($event)) {
define('ICAL_LANG', api_get_language_isocode());
$ical = new vcalendar();
$ical->setConfig('unique_id', api_get_path(WEB_PATH));
$ical->setProperty('method', 'PUBLISH');
$ical->setConfig('url', api_get_path(WEB_PATH));
$vevent = new vevent();
switch ($_GET['class']) {
case 'public':
$vevent->setClass('PUBLIC');
break;
case 'private':
$vevent->setClass('PRIVATE');
break;
case 'confidential':
$vevent->setClass('CONFIDENTIAL');
break;
default:
$vevent->setClass('PRIVATE');
break;
}
$event['start_date'] = api_get_local_time($event['start_date']);
$event['end_date'] = api_get_local_time($event['end_date']);
switch ($type) {
case 'personal':
case 'platform':
$vevent->setProperty('summary', api_convert_encoding($event['title'], 'UTF-8', $charset));
if (empty($event['start_date'])) {
header('location:'.Security::remove_XSS($_SERVER['HTTP_REFERER']));
}
list($y, $m, $d, $h, $M, $s) = preg_split('/[\s:-]/', $event['start_date']);
$vevent->setProperty(
'dtstart',
['year' => $y, 'month' => $m, 'day' => $d, 'hour' => $h, 'min' => $M, 'sec' => $s]
);
if (empty($event['end_date'])) {
$y2 = $y;
$m2 = $m;
$d2 = $d;
$h2 = $h;
$M2 = $M + 15;
$s2 = $s;
if ($M2 > 60) {
$M2 = $M2 - 60;
$h2++;
}
} else {
list($y2, $m2, $d2, $h2, $M2, $s2) = preg_split('/[\s:-]/', $event['end_date']);
}
$vevent->setProperty(
'dtend',
['year' => $y2, 'month' => $m2, 'day' => $d2, 'hour' => $h2, 'min' => $M2, 'sec' => $s2]
);
//$vevent->setProperty( 'LOCATION', get_lang('Unknown') ); // property name - case independent
$vevent->setProperty('description', api_convert_encoding($event['description'], 'UTF-8', $charset));
//$vevent->setProperty( 'comment', 'This is a comment' );
//$user = api_get_user_info($event['user']);
//$vevent->setProperty('organizer',$user['mail']);
//$vevent->setProperty('attendee',$user['mail']);
//$vevent->setProperty( 'rrule', array( 'FREQ' => 'WEEKLY', 'count' => 4));// occurs also four next weeks
$ical->setConfig('filename', $y.$m.$d.$h.$M.$s.'-'.rand(1, 1000).'.ics');
$ical->setComponent($vevent); // add event to calendar
$ical->returnCalendar();
break;
case 'course':
$vevent->setProperty('summary', api_convert_encoding($event['title'], 'UTF-8', $charset));
if (empty($event['start_date'])) {
header('location:'.Security::remove_XSS($_SERVER['HTTP_REFERER']));
}
list($y, $m, $d, $h, $M, $s) = preg_split('/[\s:-]/', $event['start_date']);
$vevent->setProperty(
'dtstart',
['year' => $y, 'month' => $m, 'day' => $d, 'hour' => $h, 'min' => $M, 'sec' => $s]
);
if (empty($event['end_date'])) {
$y2 = $y;
$m2 = $m;
$d2 = $d;
$h2 = $h;
$M2 = $M + 15;
$s2 = $s;
if ($M2 > 60) {
$M2 = $M2 - 60;
$h2++;
}
} else {
list($y2, $m2, $d2, $h2, $M2, $s2) = preg_split('/[\s:-]/', $event['end_date']);
}
$vevent->setProperty(
'dtend',
['year' => $y2, 'month' => $m2, 'day' => $d2, 'hour' => $h2, 'min' => $M2, 'sec' => $s2]
);
$vevent->setProperty('description', api_convert_encoding($event['description'], 'UTF-8', $charset));
//$vevent->setProperty( 'comment', 'This is a comment' );
//$user = api_get_user_info($event['user']);
//$vevent->setProperty('organizer',$user['mail']);
//$vevent->setProperty('attendee',$user['mail']);
//$course = api_get_course_info();
$vevent->setProperty('location', $course_info['name']); // property name - case independent
/*if($ai['repeat']) {
$trans = array('daily'=>'DAILY','weekly'=>'WEEKLY','monthlyByDate'=>'MONTHLY','yearly'=>'YEARLY');
$freq = $trans[$ai['repeat_type']];
list($e_y,$e_m,$e_d) = split('/',date('Y/m/d',$ai['repeat_end']));
$vevent->setProperty('rrule',array('FREQ'=>$freq,'UNTIL'=>array('year'=>$e_y,'month'=>$e_m,'day'=>$e_d),'INTERVAL'=>'1'));
}*/
//$vevent->setProperty( 'rrule', array( 'FREQ' => 'WEEKLY', 'count' => 4));// occurs also four next weeks
$ical->setConfig('filename', $y.$m.$d.$h.$M.$s.'-'.rand(1, 1000).'.ics');
$ical->setComponent($vevent); // add event to calendar
$ical->returnCalendar();
break;
default:
header('location:'.Security::remove_XSS($_SERVER['HTTP_REFERER']));
exit();
}
} else {
header('location:'.Security::remove_XSS($_SERVER['HTTP_REFERER']));
exit;
}

7
main/calendar/index.html Normal file
View File

@@ -0,0 +1,7 @@
<html>
<head>
<meta http-equiv="refresh" content="0; url=agenda.php">
</head>
<body>
</body>
</html>

View File

@@ -0,0 +1,62 @@
<?php
/* For licensing terms, see /license.txt */
use Chamilo\CoreBundle\Component\Utils\ChamiloApi;
$cidReset = true;
require_once __DIR__.'/../inc/global.inc.php';
api_block_anonymous_users();
$current_course_tool = TOOL_CALENDAR_EVENT;
$this_section = SECTION_MYAGENDA;
$timezone = new DateTimeZone(api_get_timezone());
$now = new DateTime('now', $timezone);
$currentYear = (int) $now->format('Y');
$searchYear = isset($_GET['year']) ? (int) $_GET['year'] : $currentYear;
$userInfo = api_get_user_info();
$userId = $userInfo['id'];
$sessions = [];
if (api_is_drh()) {
$count = SessionManager::get_sessions_followed_by_drh($userId, null, null, true);
} else {
$count = UserManager::get_sessions_by_category($userId, false, true, true, true);
}
$sessionsList = UserManager::getSubscribedSessionsByYear($userInfo, $searchYear);
if ($count > 50) {
$message = Display::return_message('TooMuchSessionsInPlanification', 'warning');
api_not_allowed(true, $message);
}
$sessions = UserManager::getSessionsCalendarByYear($sessionsList, $searchYear);
$colors = ChamiloApi::getColorPalette(false, true, count($sessions));
$agenda = new Agenda('personal');
$actions = $agenda->displayActions('list', $userId);
$toolName = get_lang('SessionsPlanCalendar');
$interbreadcrumb[] = [
'url' => api_get_path(WEB_CODE_PATH).'calendar/agenda_js.php?type=personal',
'name' => get_lang('Agenda'),
];
$template = new Template($toolName);
$template->assign('toolbar', $actions);
$template->assign('student_id', $userId);
$template->assign('search_year', $searchYear);
$template->assign('colors', $colors);
$template->assign('sessions', $sessions);
$layout = $template->get_template('agenda/planification.tpl');
$template->display($layout);