Calendar: Add agenda_event_subscriptions configuration setting - refs BT#20637

It allows to other users to subscribe for events. Requires DB changes:
```sql
ALTER TABLE personal_agenda ADD subscription_visibility INT DEFAULT 0 NOT NULL, ADD max_subscriptions INT DEFAULT 0 NOT NULL;
```

Then uncomment the "use EventSubscribableTrait;" line in the PersonalAgenda class.
pull/4668/head
Angel Fernando Quiroz Campos 2 years ago
parent b1cf75718c
commit 6c617c5798
  1. 12
      main/calendar/agenda.php
  2. 33
      main/calendar/agenda_js.php
  3. 6
      main/inc/ajax/agenda.ajax.php
  4. 117
      main/inc/lib/agenda.lib.php
  5. 1
      main/inc/lib/template.lib.php
  6. 8
      main/install/configuration.dist.php
  7. 58
      main/template/default/agenda/month.tpl
  8. 12
      src/Chamilo/CoreBundle/Entity/AgendaEventSubscription.php
  9. 3
      src/Chamilo/CoreBundle/Entity/PersonalAgenda.php
  10. 48
      src/Chamilo/CoreBundle/Traits/EventSubscribableTrait.php

@ -174,6 +174,8 @@ if ($allowToEdit) {
$notificationPeriod = $_REQUEST['notification_period'] ?? [];
$careerId = $_REQUEST['career_id'] ?? 0;
$promotionId = $_REQUEST['promotion_id'] ?? 0;
$subscriptionVisibility = (int) ($_REQUEST['subscription_visibility'] ?? 0);
$maxSubscriptions = (int) ($_REQUEST['max_subscriptions'] ?? 0);
$reminders = $notificationCount ? array_map(null, $notificationCount, $notificationPeriod) : [];
@ -194,7 +196,9 @@ if ($allowToEdit) {
$values['collective'] ?? false,
$reminders,
(int) $careerId,
(int) $promotionId
(int) $promotionId,
$subscriptionVisibility,
$maxSubscriptions
);
if (!empty($values['repeat']) && !empty($eventId)) {
@ -254,6 +258,8 @@ if ($allowToEdit) {
$notificationPeriod = $_REQUEST['notification_period'] ?? [];
$careerId = $_REQUEST['career_id'] ?? 0;
$promotionId = $_REQUEST['promotion_id'] ?? 0;
$subscriptionVisibility = (int) ($_REQUEST['subscription_visibility'] ?? 0);
$maxSubscriptions = (int) ($_REQUEST['max_subscriptions'] ?? 0);
$reminders = $notificationCount ? array_map(null, $notificationCount, $notificationPeriod) : [];
@ -307,7 +313,9 @@ if ($allowToEdit) {
$values['collective'] ?? false,
$reminders,
(int) $careerId,
(int) $promotionId
(int) $promotionId,
$subscriptionVisibility,
$maxSubscriptions
);
if (!empty($values['repeat']) && !empty($eventId)) {

@ -3,6 +3,8 @@
/* 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
@ -292,6 +294,37 @@ if (api_get_configuration_value('agenda_collective_invitations') && 'personal' =
$form->addCheckBox('collective', '', get_lang('IsItEditableByTheInvitees'));
}
if (
api_is_platform_admin()
&& api_get_configuration_value('agenda_event_subscriptions') && 'personal' === $agenda->type
) {
$form->addHeader(get_lang('Subscriptions'));
$form->addHtml('<div id="form_subscriptions_container">');
$form->addSelect(
'subscription_visibility',
get_lang('AllowSubscriptions'),
[
AgendaEventSubscription::SUBSCRIPTION_NO => get_lang('No'),
AgendaEventSubscription::SUBSCRIPTION_ALL => get_lang('AllUsersOfThePlatform'),
],
[
'onchange' => 'document.getElementById(\'max_subscriptions\').disabled = this.value == 0;',
]
);
$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>');
}
if (api_get_configuration_value('agenda_reminders')) {
$tpl->assign(
'agenda_reminders_js',

@ -51,6 +51,8 @@ switch ($action) {
$notificationPeriod = $_REQUEST['notification_period'] ?? [];
$careerId = $_REQUEST['career_id'] ?? 0;
$promotionId = $_REQUEST['promotion_id'] ?? 0;
$subscriptionVisibility = (int) ($_REQUEST['subscription_visibility'] ?? 0);
$maxSubscriptions = (int) ($_REQUEST['max_subscriptions'] ?? 0);
$reminders = $notificationCount ? array_map(null, $notificationCount, $notificationPeriod) : [];
@ -71,7 +73,9 @@ switch ($action) {
$isCollective,
$reminders,
(int) $careerId,
(int) $promotionId
(int) $promotionId,
$subscriptionVisibility,
$maxSubscriptions
);
echo $eventId;

@ -4,6 +4,7 @@
use Chamilo\CoreBundle\Entity\AgendaEventInvitation;
use Chamilo\CoreBundle\Entity\AgendaEventInvitee;
use Chamilo\CoreBundle\Entity\AgendaEventSubscription;
use Chamilo\CoreBundle\Entity\AgendaReminder;
use Chamilo\UserBundle\Entity\User;
@ -254,7 +255,9 @@ class Agenda
bool $isCollective = false,
array $reminders = [],
int $careerId = 0,
int $promotionId = 0
int $promotionId = 0,
int $subscriptionVisibility = 0,
int $maxSubscriptions = 0
) {
$start = api_get_utc_datetime($start);
$end = api_get_utc_datetime($end);
@ -281,6 +284,17 @@ class Agenda
if (api_get_configuration_value('agenda_collective_invitations')) {
Agenda::saveCollectiveProperties($inviteesList, $isCollective, $id);
}
if (api_get_configuration_value('agenda_event_subscriptions') && api_is_platform_admin()) {
Database::update(
$this->tbl_personal_agenda,
[
'subscription_visibility' => $subscriptionVisibility,
'max_subscriptions' => $subscriptionVisibility > 0 ? $maxSubscriptions : 0,
],
['id = ?' => [$id]]
);
}
break;
case 'course':
$attributes = [
@ -865,7 +879,9 @@ class Agenda
bool $isCollective = false,
array $remindersList = [],
int $careerId = 0,
int $promotionId = 0
int $promotionId = 0,
int $subscriptionVisibility = 0,
int $maxSubscriptions = 0
) {
$id = (int) $id;
$start = api_get_utc_datetime($start);
@ -909,6 +925,17 @@ class Agenda
if (api_get_configuration_value('agenda_collective_invitations')) {
Agenda::saveCollectiveProperties($inviteesList, $isCollective, $id);
}
if (api_get_configuration_value('agenda_event_subscriptions') && api_is_platform_admin()) {
Database::update(
$this->tbl_personal_agenda,
[
'subscription_visibility' => $subscriptionVisibility,
'max_subscriptions' => $subscriptionVisibility > 0 ? $maxSubscriptions : 0,
],
['id = ?' => [$id]]
);
}
break;
case 'course':
$eventInfo = $this->get_event($id);
@ -1759,6 +1786,7 @@ class Agenda
$endCondition = '';
$agendaCollectiveInvitations = api_get_configuration_value('agenda_collective_invitations');
$agendaEventSubscriptions = api_get_configuration_value('agenda_event_subscriptions');
if ($start !== 0) {
$startDate = api_get_utc_datetime($start, true, true);
@ -1770,8 +1798,37 @@ class Agenda
}
$user_id = api_get_user_id();
$userCondition = "user = $user_id";
if ($agendaEventSubscriptions) {
$objGroup = new UserGroup();
$groupList = $objGroup->get_groups_by_user($user_id);
$userCondition = "(
$userCondition
OR (
subscription_visibility = ".AgendaEventSubscription::SUBSCRIPTION_ALL;
if ($groupList) {
$userCondition .= "
OR (
subscription_visibility = ".AgendaEventSubscription::SUBSCRIPTION_CLASS."
AND subscription_item_id IN (".implode(', ', array_keys($groupList)).")
)
";
}
$userCondition .= "
)
)
";
}
$sql = "SELECT * FROM ".$this->tbl_personal_agenda."
WHERE user = $user_id $startCondition $endCondition";
WHERE $userCondition
$startCondition
$endCondition
";
$result = Database::query($sql);
$my_events = [];
@ -1782,7 +1839,7 @@ class Agenda
$event['title'] = $row['title'];
$event['className'] = 'personal';
$event['borderColor'] = $event['backgroundColor'] = $this->event_personal_color;
$event['editable'] = true;
$event['editable'] = $user_id === (int) $row['user'];
$event['sent_to'] = get_lang('Me');
$event['type'] = 'personal';
@ -1806,6 +1863,11 @@ class Agenda
$event['invitees'] = self::getInviteesForPersonalEvent($row['id']);
}
if ($agendaEventSubscriptions) {
$event['subscription_visibility'] = (int) $row['subscription_visibility'];
$event['max_subscriptions'] = (int) $row['max_subscriptions'];
}
$my_events[] = $event;
$this->events[] = $event;
}
@ -2680,6 +2742,9 @@ class Agenda
$action = isset($params['action']) ? Security::remove_XSS($params['action']) : null;
$id = isset($params['id']) ? (int) $params['id'] : 0;
$em = Database::getManager();
$personalEvent = $id ? $em->find('ChamiloCoreBundle:PersonalAgenda', $id) : null;
$url = api_get_self().'?action='.$action.'&id='.$id.'&type='.$this->type;
if ($this->type == 'course') {
$url = api_get_self().'?'.api_get_cidreq().'&action='.$action.'&id='.$id.'&type='.$this->type;
@ -2894,14 +2959,11 @@ class Agenda
$agendaCollectiveInvitations = api_get_configuration_value('agenda_collective_invitations');
if ($agendaCollectiveInvitations && 'personal' === $this->type) {
$em = Database::getManager();
$invitees = [];
$isCollective = false;
if ($id) {
$event = $em->find('ChamiloCoreBundle:PersonalAgenda', $id);
$eventInvitation = $event->getInvitation();
if ($personalEvent) {
$eventInvitation = $personalEvent->getInvitation();
if ($eventInvitation) {
foreach ($eventInvitation->getInvitees() as $invitee) {
@ -2911,7 +2973,7 @@ class Agenda
}
}
$isCollective = $event->isCollective();
$isCollective = $personalEvent->isCollective();
}
$form->addSelectAjax(
@ -2924,6 +2986,7 @@ class Agenda
]
);
$form->addCheckBox('collective', '', get_lang('IsItEditableByTheInvitees'));
$form->addHtml('<hr>');
$params['invitees'] = array_keys($invitees);
$params['collective'] = $isCollective;
@ -2941,6 +3004,40 @@ class Agenda
$form->addHtml('<hr>');
}
if (api_is_platform_admin()
&& true === api_get_configuration_value('agenda_event_subscriptions')
) {
$form->addSelect(
'subscription_visibility',
get_lang('AllowSubscriptions'),
[
AgendaEventSubscription::SUBSCRIPTION_NO => get_lang('No'),
AgendaEventSubscription::SUBSCRIPTION_ALL => get_lang('AllUsersOfThePlatform'),
]
);
$form->addNumeric(
'max_subscriptions',
['', get_lang('MaxSubscriptionsLeaveEmptyToNotLimit')],
[
'disabled' => 'disabled',
'step' => 1,
'min' => 0,
'value' => 0,
]
);
$form->addHtml("<script>
$(function () {
$('#add_event_subscription_visibility')
.on('change', function () {
$('#max_subscriptions').prop('disabled', this.value == 0);
})
.trigger('change');
})
</script>
");
$form->addHtml('<hr>');
}
if (api_get_configuration_value('allow_careers_in_global_agenda') && 'admin' === $this->type) {
Career::addCareerFieldsToForm($form);
$form->addHtml('<hr>');

@ -200,6 +200,7 @@ class Template
$functions = [
['name' => 'get_tutors_names', 'callable' => 'Template::returnTutorsNames'],
['name' => 'get_teachers_names', 'callable' => 'Template::returnTeachersNames'],
['name' => 'api_is_platform_admin', 'callable' => 'api_is_platform_admin'],
];
foreach ($functions as $function) {

@ -462,6 +462,14 @@ CREATE UNIQUE INDEX UNIQ_D8612460AF68C6B ON personal_agenda (agenda_event_invita
// Then add the "@" symbol to AgendaEventInvitation and AgendaEventInvitee classes in the ORM\Entity() line.
// Then uncomment the "use EventCollectiveTrait;" line in the PersonalAgenda class.
//$_configuration['agenda_collective_invitations'] = false;
// It allows to other users to subscribe for events. Requires DB changes:
/*
ALTER TABLE personal_agenda ADD subscription_visibility INT DEFAULT 0 NOT NULL, ADD max_subscriptions INT DEFAULT 0 NOT NULL;
*/
// Then uncomment the "use EventSubscribableTrait;" line in the PersonalAgenda class.
//$_configuration['agenda_event_subscriptions'] = false;
// Enable reminders for agenda events. Requires database changes:
/*
CREATE TABLE agenda_reminder (id BIGINT AUTO_INCREMENT NOT NULL, type VARCHAR(255) NOT NULL, event_id INT NOT NULL, date_interval VARCHAR(255) NOT NULL COMMENT '(DC2Type:dateinterval)', sent TINYINT(1) NOT NULL, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB;

@ -1,4 +1,5 @@
{% set agenda_collective_invitations = 'agenda_collective_invitations'|api_get_configuration_value %}
{% set agenda_event_subscriptions = 'agenda_event_subscriptions'|api_get_configuration_value %}
{% set agenda_reminders = 'agenda_reminders'|api_get_configuration_value %}
{% set career_in_global_events = 'allow_careers_in_global_agenda'|api_get_configuration_value %}
@ -340,6 +341,15 @@ $(function() {
//Reset the CKEditor content that persist in memory
CKEDITOR.instances['content'].setData('');
allFields.removeClass("ui-state-error");
$('#add_event_form').get(0).reset();
{% if agenda_event_subscriptions and 'personal' == type and api_is_platform_admin() %}
$('#form_subscription_visibility').trigger('change').selectpicker('refresh');
$('#form_subscriptions_container').show('');
$('#form_subscriptions_edit').hide().html('');
{% endif %}
$("#dialog-form").dialog("open");
$("#dialog-form").dialog({
buttons: {
@ -582,6 +592,13 @@ $(function() {
}
{% endif %}
{% if agenda_event_subscriptions and 'personal' == type and api_is_platform_admin() %}
$('#form_subscriptions_container').hide();
$('#form_subscriptions_edit')
.html(showSubcriptionsContainer(calEvent))
.show();
{% endif %}
{% if agenda_reminders %}
$('#notification_list').html('').next('.form-group').hide();
@ -925,6 +942,10 @@ $(function() {
});
{% endif %}
{% if agenda_event_subscriptions and 'personal' == type %}
$('#simple_subscriptions').html(showSubcriptionsContainer(calEvent));
{% endif %}
var buttons = {
'{{"ExportiCalConfidential"|get_lang}}' : function() {
url = "ical_export.php?id=" + calEvent.id+'&course_id='+calEvent.course_id+"&class=confidential";
@ -1004,6 +1025,36 @@ $(function() {
});
{{ agenda_reminders_js }}
function showSubcriptionsContainer (calEvent) {
if (0 === calEvent.subscription_visibility) {
return '';
}
var html = '';
html += '<dl class="dl-horizontal">';
html += "<dt>{{ 'AllowSubscriptions'|get_lang }}</dt>";
html += '<dd>';
if (1 === calEvent.subscription_visibility) {
html += "{{ 'AllUsersOfThePlatform'|get_lang }}";
}
if (2 === calEvent.subscription_visibility) {
html += "{{ 'UsersInsideClass'|get_lang }}";
}
html += '</dd>';
if (0 <= calEvent.max_subscriptions) {
html += "<dt>{{ 'MaxSubcriptions'|get_lang }}</dt>";
html += '<dd>' + calEvent.max_subscriptions + '</dd>';
}
html += '</dl>';
return html;
}
});
</script>
{{ actions_div }}
@ -1090,6 +1141,13 @@ $(function() {
</div>
</div>
{% endif %}
{% if agenda_event_subscriptions and 'personal' == type %}
<div class="form-group">
<label class="col-sm-3 control-label">{{ 'Subscriptions' }}</label>
<div class="col-sm-9" id="simple_subscriptions"></div>
</div>
{% endif %}
</form>
</div>

@ -0,0 +1,12 @@
<?php
/* For licensing terms, see /license.txt */
namespace Chamilo\CoreBundle\Entity;
class AgendaEventSubscription
{
public const SUBSCRIPTION_NO = 0;
public const SUBSCRIPTION_ALL = 1;
public const SUBSCRIPTION_CLASS = 2;
}

@ -4,6 +4,7 @@
namespace Chamilo\CoreBundle\Entity;
use Chamilo\CoreBundle\Traits\EventCollectiveTrait;
use Chamilo\CoreBundle\Traits\EventSubscribableTrait;
use Doctrine\ORM\Mapping as ORM;
/**
@ -17,6 +18,8 @@ class PersonalAgenda
{
// Uncomment next line when activating the agenda_collective_invitations configuration setting.
//use EventCollectiveTrait;
// Uncomment next line when activating the agenda_event_subscriptions configuration setting.
//use EventSubscribableTrait;
/**
* @var int

@ -0,0 +1,48 @@
<?php
/* For licensing terms, see /license.txt */
namespace Chamilo\CoreBundle\Traits;
use Doctrine\ORM\Mapping as ORM;
trait EventSubscribableTrait
{
/**
* @var int
*
* @ORM\Column(name="subscription_visibility", type="integer", options={"default": 0})
*/
protected $subscriptionVisibility = 0;
/**
* @var int
*
* @ORM\Column(name="max_subscriptions", type="integer", options={"default": 0})
*/
protected $maxSubscriptions = 0;
public function getSubscriptionVisibility(): int
{
return $this->subscriptionVisibility;
}
public function setSubscriptionVisibility(int $subscriptionVisibility): self
{
$this->subscriptionVisibility = $subscriptionVisibility;
return $this;
}
public function getMaxSubscriptions(): int
{
return $this->maxSubscriptions;
}
public function setMaxSubscriptions(int $maxSubscriptions): self
{
$this->maxSubscriptions = $maxSubscriptions;
return $this;
}
}
Loading…
Cancel
Save