Allow contact lists as event participants

This commit is contained in:
nathangray 2016-07-06 13:18:36 -06:00
parent c0e480f465
commit 76307c4bbf
9 changed files with 125 additions and 26 deletions

View File

@ -251,6 +251,11 @@ class calendar_bo
'info' => __CLASS__.'::email_info',
'app' => 'email',
);
$this->resources['l'] = array(
'type' => 'l',// one char type-identifier for this resources
'info' => __CLASS__ .'::mailing_lists',// info method, returns array with id, type & name for a given id
'app' => 'Mailing list'
);
$this->resources[''] = array(
'type' => '',
'app' => 'api-accounts',
@ -327,6 +332,36 @@ class calendar_bo
return $data;
}
/**
* returns info about mailing lists as participants
*
* @param int|array $ids single mailing list ID or array of id's
* @return array
*/
static function mailing_lists($ids)
{
if(!is_array($ids))
{
$ids = array($ids);
}
$data = array();
// Email list
$contacts_obj = new Api\Contacts();
foreach($ids as $id)
{
$list = $contacts_obj->read_list((int)$id);
$data[] = array(
'res_id' => $id,
'rights' => self::ACL_READ_FOR_PARTICIPANTS,
'name' => $list['list_name'],
);
}
return $data;
}
/**
* Add group-members as participants with status 'G'
*
@ -374,6 +409,35 @@ class calendar_bo
foreach($_users as $user)
{
$user = trim($user);
// Handle email lists
if(!is_numeric($user) && $user[0] == 'l')
{
$contacts = new Api\Contacts();
if($contacts->check_list((int)substr($user,1), ACL::READ))
{
$users[] = $user;
$options = array('list' => substr($user,1));
$lists = $contacts->search('',true,'','','',false,'AND',false,$options);
if(!$lists)
{
continue;
}
foreach($lists as &$contact)
{
$contact = 'c'.$contact['id'];
if ($ignore_acl || $this->check_perms(ACL::READ|self::ACL_READ_FOR_PARTICIPANTS|($use_freebusy?self::ACL_FREEBUSY:0),0,$contact))
{
if ($contact && !in_array($contact,$users)) // already added?
{
$users[] = $contact;
}
}
}
}
continue;
}
if ($ignore_acl || $this->check_perms(ACL::READ|self::ACL_READ_FOR_PARTICIPANTS|($use_freebusy?self::ACL_FREEBUSY:0),0,$user))
{
if ($user && !in_array($user,$users)) // already added?

View File

@ -825,6 +825,7 @@ class calendar_boupdate extends calendar_bo
$event = $msg_type == MSG_ADDED || $msg_type == MSG_MODIFIED ? $new_event : $old_event;
// add all group-members to the notification, unless they are already participants
$contact_obj = false;
foreach($to_notify as $userid => $statusid)
{
if (is_numeric($userid) && $GLOBALS['egw']->accounts->get_type($userid) == 'g' &&
@ -838,6 +839,28 @@ class calendar_boupdate extends calendar_bo
}
}
}
// Mailing lists
else if (!is_numeric($userid) && $userid[0] == 'l')
{
if(!$contact_obj)
{
$contact_obj = new Api\Contacts();
}
$options = array('list' => substr($user,1));
$contacts = $contact_obj->search('',true,'','','',false,'AND',false,$options);
if(!$contacts)
{
continue;
}
foreach($contacts as &$contact)
{
$contact = 'c'.$contact['id'];
if ($contact && !isset($to_notify[$contact])) // already added?
{
$to_notify[$contact] = 'G';
}
}
}
}
$user_prefs = $GLOBALS['egw_info']['user']['preferences'];
$startdate = new Api\DateTime($event['start']);

View File

@ -151,13 +151,30 @@ class calendar_owner_etemplate_widget extends Etemplate\Widget\Taglist
{
$account_options = $options + array('account_type' => 'both');
$_results += Api\Accounts::link_query($query, $account_options);
if (!empty($_REQUEST['checkgrants'])) $_results = array_intersect_key($_results, $GLOBALS['egw']->acl->get_grants('calendar'));
if (!empty($_REQUEST['checkgrants']))
{
$_results = array_intersect_key($_results, $GLOBALS['egw']->acl->get_grants('calendar'));
}
}
else if ($data['app'] && Link::get_registry($data['app'], 'query'))
{
$_results = Link::query($data['app'], $query,$options);
}
if(!$_results) continue;
if ($type == 'l')
{
// Include mailing lists
$contacts_obj = new Api\Contacts();
$_results += array_filter(
$contacts_obj->get_lists(Api\Acl::READ),
function($element) use($query) {
return (stripos($element, $query) !== false);
}
);
}
if(!$_results)
{
continue;
}
foreach(array_unique($_results) as $id => $title)
{

View File

@ -2755,6 +2755,7 @@ app.classes.calendar = (function(){ "use strict"; return AppJS.extend(
jQuery.extend({}, state, {owner: value[i].owner}),
this.sidebox_et2 ? null : this.et2.getInstanceManager()
);
need_data = false;
}
}

View File

@ -927,6 +927,10 @@ et2_calendar_event.owner_check = function owner_check(event, parent, owner_too)
var length = parent_owner.length;
for(var i = 0; i < length; i++ )
{
// Exception for mailing lists, they won't match and we don't have the
// list client side.
if(parent_owner[i][0] === 'l') return true;
if (parseInt(parent_owner[i]) < 0)
{
// Add in groups, if we can get them (this is syncronous)

View File

@ -108,7 +108,7 @@ var et2_calendar_timegrid = (function(){ "use strict"; return et2_calendar_view.
.appendTo(this.scrolling);
// Used for owners
this.owner = et2_createWidget('select-account_ro',{},this);
this.owner = et2_createWidget('description',{},this);
this._labelContainer = jQuery(document.createElement("label"))
.addClass("et2_label et2_link")
@ -1577,17 +1577,7 @@ var et2_calendar_timegrid = (function(){ "use strict"; return et2_calendar_view.
if(typeof _owner == 'string' && isNaN(_owner))
{
this.set_label('');
switch(_owner[0])
{
case 'c':
this.owner.options.application = 'addressbook';
this.owner.set_value(_owner.substr(1));
break;
case 'r':
this.owner.options.application = 'resources';
this.owner.set_value(_owner.substr(1));
break;
}
this.owner.set_value(this._get_owner_name(_owner));
// Label is empty, but give extra space for the owner name
this.div.removeClass('calendar_TimeGridNoLabel');
@ -1606,7 +1596,7 @@ var et2_calendar_timegrid = (function(){ "use strict"; return et2_calendar_view.
else
{
this.owner.options.application = 'api-accounts';
this.owner.set_value(typeof _owner == "string" || typeof _owner == "number" ? _owner : jQuery.extend([],_owner));
this.owner.set_value(this._get_owner_name(_owner));
this.set_label('');
jQuery(this.getDOMNode(this.owner)).prepend(this.owner.getDOMNode());
}

View File

@ -341,7 +341,7 @@ var et2_calendar_view = (function(){ "use strict"; return et2_valueWidget.extend
var options = false
if(app.calendar && app.calendar.sidebox_et2 && app.calendar.sidebox_et2.getWidgetById('owner'))
{
options = app.calendar.sidebox_et2.getWidgetById('owner').options.select_options;
options = app.calendar.sidebox_et2.getWidgetById('owner').taglist.getSelection();
}
else
{

View File

@ -39,10 +39,10 @@
}
/* Let hidden user names be visible */
#calendar-view_view.hideDayColHeader tr:not(:first-of-type) .calendar_calGridHeader > ul {
#calendar-view_view.hideDayColHeader tr:not(:first-of-type) .calendar_calGridHeader > span.et2_label {
position: static;
}
#calendar-view_view.hideDayColHeader tr:not(:first-of-type) .calendar_calGridHeader > ul > li {
#calendar-view_view.hideDayColHeader tr:not(:first-of-type) .calendar_calGridHeader > span.et2_label {
overflow: visible !important;
}
}
@ -313,12 +313,12 @@ Hide subsequent headers in week view with non-consolidated owners
#calendar-view_view.hideDayColHeader tr:not(:first-of-type) .calendar_calGridHeader .calendar_calDayColHeader > div[data-date] {
display:none;
}
#calendar-view_view.hideDayColHeader tr .calendar_calGridHeader > ul > li {
#calendar-view_view.hideDayColHeader tr .calendar_calGridHeader > span.et2_label {
white-space:nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
#calendar-view_view.hideDayColHeader tr .calendar_calGridHeader > ul:hover {
#calendar-view_view.hideDayColHeader tr .calendar_calGridHeader > span.et2_label:hover {
overflow: visible;
width: auto;
background-color: inherit;
@ -535,7 +535,7 @@ Hide subsequent headers in week view with non-consolidated owners
text-align: center;
}
.calendar_calGridHeader > ul {
.calendar_calGridHeader > span.et2_label {
position: absolute;
width: 55px;
}

View File

@ -51,10 +51,10 @@
overflow-y: hidden !important;
}
/* Let hidden user names be visible */
#calendar-view_view.hideDayColHeader tr:not(:first-of-type) .calendar_calGridHeader > ul {
#calendar-view_view.hideDayColHeader tr:not(:first-of-type) .calendar_calGridHeader > span.et2_label {
position: static;
}
#calendar-view_view.hideDayColHeader tr:not(:first-of-type) .calendar_calGridHeader > ul > li {
#calendar-view_view.hideDayColHeader tr:not(:first-of-type) .calendar_calGridHeader > span.et2_label {
overflow: visible !important;
}
}
@ -316,12 +316,12 @@ Hide subsequent headers in week view with non-consolidated owners
#calendar-view_view.hideDayColHeader tr:not(:first-of-type) .calendar_calGridHeader .calendar_calDayColHeader > div[data-date] {
display: none;
}
#calendar-view_view.hideDayColHeader tr .calendar_calGridHeader > ul > li {
#calendar-view_view.hideDayColHeader tr .calendar_calGridHeader > span.et2_label {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
#calendar-view_view.hideDayColHeader tr .calendar_calGridHeader > ul:hover {
#calendar-view_view.hideDayColHeader tr .calendar_calGridHeader > span.et2_label:hover {
overflow: visible;
width: auto;
background-color: inherit;
@ -532,7 +532,7 @@ Hide subsequent headers in week view with non-consolidated owners
width: 58px;
text-align: center;
}
.calendar_calGridHeader > ul {
.calendar_calGridHeader > span.et2_label {
position: absolute;
width: 55px;
}