Use IMAP permissions to determine possible actions on the client (#4827)
s/writeable/editable/
This commit is contained in:
parent
c92c8e9ed0
commit
8792a668b6
8 changed files with 61 additions and 41 deletions
|
@ -265,7 +265,7 @@ class calendar extends rcube_plugin
|
||||||
$default_id = $this->rc->config->get('calendar_default_calendar');
|
$default_id = $this->rc->config->get('calendar_default_calendar');
|
||||||
$calendars = $this->driver->list_calendars(calendar_driver::FILTER_PERSONAL);
|
$calendars = $this->driver->list_calendars(calendar_driver::FILTER_PERSONAL);
|
||||||
$calendar = $calendars[$default_id] ?: null;
|
$calendar = $calendars[$default_id] ?: null;
|
||||||
if (!$calendar || $confidential || ($writeable && !$calendar['writeable'])) {
|
if (!$calendar || $confidential || ($writeable && !$calendar['editable'])) {
|
||||||
foreach ($calendars as $cal) {
|
foreach ($calendars as $cal) {
|
||||||
if ($confidential && $cal['subtype'] == 'confidential') {
|
if ($confidential && $cal['subtype'] == 'confidential') {
|
||||||
$calendar = $cal;
|
$calendar = $cal;
|
||||||
|
@ -276,7 +276,7 @@ class calendar extends rcube_plugin
|
||||||
if (!$confidential)
|
if (!$confidential)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!$writeable || $cal['writeable']) {
|
if (!$writeable || $cal['editable']) {
|
||||||
$first = $cal;
|
$first = $cal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2459,7 +2459,7 @@ class calendar extends rcube_plugin
|
||||||
$calendar_select->add('--', '');
|
$calendar_select->add('--', '');
|
||||||
$numcals = 0;
|
$numcals = 0;
|
||||||
foreach ($calendars as $calendar) {
|
foreach ($calendars as $calendar) {
|
||||||
if ($calendar['writeable']) {
|
if ($calendar['editable']) {
|
||||||
$calendar_select->add($calendar['name'], $calendar['id']);
|
$calendar_select->add($calendar['name'], $calendar['id']);
|
||||||
$numcals++;
|
$numcals++;
|
||||||
}
|
}
|
||||||
|
@ -2840,7 +2840,7 @@ class calendar extends rcube_plugin
|
||||||
}
|
}
|
||||||
|
|
||||||
// save to calendar
|
// save to calendar
|
||||||
if ($calendar && $calendar['writeable']) {
|
if ($calendar && $calendar['editable']) {
|
||||||
// check for existing event with the same UID
|
// check for existing event with the same UID
|
||||||
$existing = $this->driver->get_event($event, calendar_driver::FILTER_WRITEABLE | calendar_driver::FILTER_PERSONAL);
|
$existing = $this->driver->get_event($event, calendar_driver::FILTER_WRITEABLE | calendar_driver::FILTER_PERSONAL);
|
||||||
|
|
||||||
|
@ -3107,7 +3107,7 @@ class calendar extends rcube_plugin
|
||||||
foreach ($events as $event) {
|
foreach ($events as $event) {
|
||||||
// save to calendar
|
// save to calendar
|
||||||
$calendar = $calendars[$cal_id] ?: $this->get_default_calendar(true, $event['sensitivity'] == 'confidential');
|
$calendar = $calendars[$cal_id] ?: $this->get_default_calendar(true, $event['sensitivity'] == 'confidential');
|
||||||
if ($calendar && $calendar['writeable'] && $event['_type'] == 'event') {
|
if ($calendar && $calendar['editable'] && $event['_type'] == 'event') {
|
||||||
$event['calendar'] = $calendar['id'];
|
$event['calendar'] = $calendar['id'];
|
||||||
|
|
||||||
if (!$this->driver->get_event($event['uid'], calendar_driver::FILTER_WRITEABLE)) {
|
if (!$this->driver->get_event($event['uid'], calendar_driver::FILTER_WRITEABLE)) {
|
||||||
|
|
|
@ -63,7 +63,7 @@ function rcube_calendar_ui(settings)
|
||||||
var resources_data = {};
|
var resources_data = {};
|
||||||
var resources_index = [];
|
var resources_index = [];
|
||||||
var resource_owners = {};
|
var resource_owners = {};
|
||||||
var resources_events_source = { url:null, editable:false, insertable:false };
|
var resources_events_source = { url:null, editable:false };
|
||||||
var freebusy_ui = { workinhoursonly:false, needsupdate:false };
|
var freebusy_ui = { workinhoursonly:false, needsupdate:false };
|
||||||
var freebusy_data = {};
|
var freebusy_data = {};
|
||||||
var current_view = null;
|
var current_view = null;
|
||||||
|
@ -309,6 +309,26 @@ function rcube_calendar_ui(settings)
|
||||||
return is_attendee(event, 'ORGANIZER', email) || !event.id;
|
return is_attendee(event, 'ORGANIZER', email) || !event.id;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check permissions on the given calendar object
|
||||||
|
*/
|
||||||
|
var has_permission = function(cal, perm)
|
||||||
|
{
|
||||||
|
// multiple chars means "either of"
|
||||||
|
if (String(perm).length > 1) {
|
||||||
|
for (var i=0; i < perm.length; i++) {
|
||||||
|
if (has_permission(cal, perm[i]))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cal.rights && String(cal.rights).indexOf(perm) >= 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (perm == 'i' && cal.editable) || (perm == 'v' && cal.editable);
|
||||||
|
}
|
||||||
|
|
||||||
var load_attachment = function(event, att)
|
var load_attachment = function(event, att)
|
||||||
{
|
{
|
||||||
var query = { _id: att.id, _event: event.recurrence_id || event.id, _cal:event.calendar, _frame: 1 };
|
var query = { _id: att.id, _event: event.recurrence_id || event.id, _cal:event.calendar, _frame: 1 };
|
||||||
|
@ -392,7 +412,7 @@ function rcube_calendar_ui(settings)
|
||||||
var event_show_dialog = function(event, ev, temp)
|
var event_show_dialog = function(event, ev, temp)
|
||||||
{
|
{
|
||||||
var $dialog = $("#eventshow");
|
var $dialog = $("#eventshow");
|
||||||
var calendar = event.calendar && me.calendars[event.calendar] ? me.calendars[event.calendar] : { editable:false, insertable:false };
|
var calendar = event.calendar && me.calendars[event.calendar] ? me.calendars[event.calendar] : { editable:false, rights:'lrs' };
|
||||||
|
|
||||||
if (!temp)
|
if (!temp)
|
||||||
me.selected_event = event;
|
me.selected_event = event;
|
||||||
|
@ -545,7 +565,7 @@ function rcube_calendar_ui(settings)
|
||||||
.html(Q(rcmail.gettext('itip' + mystatus, 'libcalendaring')));
|
.html(Q(rcmail.gettext('itip' + mystatus, 'libcalendaring')));
|
||||||
}
|
}
|
||||||
|
|
||||||
var show_rsvp = rsvp && !is_organizer(event) && event.status != 'CANCELLED';
|
var show_rsvp = rsvp && !is_organizer(event) && event.status != 'CANCELLED' && has_permission(calendar, 'v');
|
||||||
$('#event-rsvp')[(show_rsvp ? 'show' : 'hide')]();
|
$('#event-rsvp')[(show_rsvp ? 'show' : 'hide')]();
|
||||||
$('#event-rsvp .rsvp-buttons input').prop('disabled', false).filter('input[rel='+mystatus+']').prop('disabled', true);
|
$('#event-rsvp .rsvp-buttons input').prop('disabled', false).filter('input[rel='+mystatus+']').prop('disabled', true);
|
||||||
|
|
||||||
|
@ -572,6 +592,8 @@ function rcube_calendar_ui(settings)
|
||||||
event_edit_dialog('edit', event);
|
event_edit_dialog('edit', event);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
if (!temp && has_permission(calendar, 'td') && event.editable !== false) {
|
||||||
buttons.push({
|
buttons.push({
|
||||||
text: rcmail.gettext('delete', 'calendar'),
|
text: rcmail.gettext('delete', 'calendar'),
|
||||||
'class': 'delete',
|
'class': 'delete',
|
||||||
|
@ -581,7 +603,8 @@ function rcube_calendar_ui(settings)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
|
if (!buttons.length) {
|
||||||
buttons.push({
|
buttons.push({
|
||||||
text: rcmail.gettext('close', 'calendar'),
|
text: rcmail.gettext('close', 'calendar'),
|
||||||
click: function(){
|
click: function(){
|
||||||
|
@ -687,7 +710,7 @@ function rcube_calendar_ui(settings)
|
||||||
$("#eventshow:ui-dialog").data('opener', null).dialog('close');
|
$("#eventshow:ui-dialog").data('opener', null).dialog('close');
|
||||||
|
|
||||||
var $dialog = $('<div>');
|
var $dialog = $('<div>');
|
||||||
var calendar = event.calendar && me.calendars[event.calendar] ? me.calendars[event.calendar] : { insertable:action=='new' };
|
var calendar = event.calendar && me.calendars[event.calendar] ? me.calendars[event.calendar] : { editable:true, rights: action=='new' ? 'lrwitd' : 'lrs' };
|
||||||
me.selected_event = $.extend($.extend({}, event_defaults), event); // clone event object (with defaults)
|
me.selected_event = $.extend($.extend({}, event_defaults), event); // clone event object (with defaults)
|
||||||
event = me.selected_event; // change reference to clone
|
event = me.selected_event; // change reference to clone
|
||||||
freebusy_ui.needsupdate = false;
|
freebusy_ui.needsupdate = false;
|
||||||
|
@ -737,7 +760,7 @@ function rcube_calendar_ui(settings)
|
||||||
// set calendar selection according to permissions
|
// set calendar selection according to permissions
|
||||||
calendars.find('option').each(function(i, opt) {
|
calendars.find('option').each(function(i, opt) {
|
||||||
var cal = me.calendars[opt.value] || {};
|
var cal = me.calendars[opt.value] || {};
|
||||||
$(opt).prop('disabled', !(cal.editable || (action == 'new' && cal.insertable)))
|
$(opt).prop('disabled', !(cal.editable || (action == 'new' && has_permission(cal, 'i'))))
|
||||||
});
|
});
|
||||||
|
|
||||||
// set alarm(s)
|
// set alarm(s)
|
||||||
|
@ -3559,8 +3582,6 @@ function rcube_calendar_ui(settings)
|
||||||
|
|
||||||
me.calendars[id] = $.extend({
|
me.calendars[id] = $.extend({
|
||||||
url: rcmail.url('calendar/load_events', { source: id }),
|
url: rcmail.url('calendar/load_events', { source: id }),
|
||||||
editable: cal.writeable || false,
|
|
||||||
insertable: cal.insert || false,
|
|
||||||
className: 'fc-event-cal-'+id,
|
className: 'fc-event-cal-'+id,
|
||||||
id: id
|
id: id
|
||||||
}, cal);
|
}, cal);
|
||||||
|
@ -3590,7 +3611,7 @@ function rcube_calendar_ui(settings)
|
||||||
|
|
||||||
// insert to #calendar-select options if writeable
|
// insert to #calendar-select options if writeable
|
||||||
select = $('#edit-calendar');
|
select = $('#edit-calendar');
|
||||||
if (fc && (cal.writeable || cal.insert) && select.length && !select.find('option[value="'+id+'"]').length) {
|
if (fc && has_permission(cal, 'i') && select.length && !select.find('option[value="'+id+'"]').length) {
|
||||||
$('<option>').attr('value', id).html(cal.name).appendTo(select);
|
$('<option>').attr('value', id).html(cal.name).appendTo(select);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3625,7 +3646,7 @@ function rcube_calendar_ui(settings)
|
||||||
count_sources.push(id);
|
count_sources.push(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cal.writeable && !this.selected_calendar) {
|
if (cal.editable && !this.selected_calendar) {
|
||||||
this.selected_calendar = id;
|
this.selected_calendar = id;
|
||||||
rcmail.enable_command('addevent', true);
|
rcmail.enable_command('addevent', true);
|
||||||
}
|
}
|
||||||
|
@ -3776,8 +3797,7 @@ function rcube_calendar_ui(settings)
|
||||||
color: '#fff',
|
color: '#fff',
|
||||||
textColor: '#333',
|
textColor: '#333',
|
||||||
editable: false,
|
editable: false,
|
||||||
writeable: false,
|
rights: 'lrs',
|
||||||
insertable: false,
|
|
||||||
attendees: true
|
attendees: true
|
||||||
};
|
};
|
||||||
event_sources.push(me.calendars['--invitation--itip']);
|
event_sources.push(me.calendars['--invitation--itip']);
|
||||||
|
|
|
@ -89,8 +89,8 @@ class database_driver extends calendar_driver
|
||||||
$arr['active'] = !in_array($arr['id'], $hidden);
|
$arr['active'] = !in_array($arr['id'], $hidden);
|
||||||
$arr['name'] = html::quote($arr['name']);
|
$arr['name'] = html::quote($arr['name']);
|
||||||
$arr['listname'] = html::quote($arr['name']);
|
$arr['listname'] = html::quote($arr['name']);
|
||||||
$arr['insert'] = true;
|
$arr['rights'] = 'lrswikxteav';
|
||||||
$arr['writeable'] = true;
|
$arr['editable'] = true;
|
||||||
$this->calendars[$arr['calendar_id']] = $arr;
|
$this->calendars[$arr['calendar_id']] = $arr;
|
||||||
$calendar_ids[] = $this->rc->db->quote($arr['calendar_id']);
|
$calendar_ids[] = $this->rc->db->quote($arr['calendar_id']);
|
||||||
}
|
}
|
||||||
|
@ -141,7 +141,7 @@ class database_driver extends calendar_driver
|
||||||
'showalarms' => (bool)$this->rc->config->get('calendar_birthdays_alarm_type'),
|
'showalarms' => (bool)$this->rc->config->get('calendar_birthdays_alarm_type'),
|
||||||
'active' => !in_array($id, $hidden),
|
'active' => !in_array($id, $hidden),
|
||||||
'group' => 'x-birthdays',
|
'group' => 'x-birthdays',
|
||||||
'writeable' => false,
|
'editable' => false,
|
||||||
'default' => false,
|
'default' => false,
|
||||||
'children' => false,
|
'children' => false,
|
||||||
);
|
);
|
||||||
|
|
|
@ -27,8 +27,8 @@
|
||||||
class kolab_calendar extends kolab_storage_folder_api
|
class kolab_calendar extends kolab_storage_folder_api
|
||||||
{
|
{
|
||||||
public $ready = false;
|
public $ready = false;
|
||||||
public $writeable = false;
|
public $rights = 'lrs';
|
||||||
public $insert = false;
|
public $editable = false;
|
||||||
public $attachments = true;
|
public $attachments = true;
|
||||||
public $alarms = false;
|
public $alarms = false;
|
||||||
public $history = false;
|
public $history = false;
|
||||||
|
@ -82,17 +82,16 @@ class kolab_calendar extends kolab_storage_folder_api
|
||||||
// Set writeable and alarms flags according to folder permissions
|
// Set writeable and alarms flags according to folder permissions
|
||||||
if ($this->ready) {
|
if ($this->ready) {
|
||||||
if ($this->storage->get_namespace() == 'personal') {
|
if ($this->storage->get_namespace() == 'personal') {
|
||||||
$this->writeable = true;
|
$this->editable = true;
|
||||||
$this->insert = true;
|
$this->rights = 'lrswikxteav';
|
||||||
$this->alarms = true;
|
$this->alarms = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$rights = $this->storage->get_myrights();
|
$rights = $this->storage->get_myrights();
|
||||||
if ($rights && !PEAR::isError($rights)) {
|
if ($rights && !PEAR::isError($rights)) {
|
||||||
if (strpos($rights, 'i') !== false)
|
$this->rights = $rights;
|
||||||
$this->insert = true;
|
|
||||||
if (strpos($rights, 't') !== false || strpos($rights, 'd') !== false)
|
if (strpos($rights, 't') !== false || strpos($rights, 'd') !== false)
|
||||||
$this->writeable = $this->insert;
|
$this->editable = strpos($rights, 'i');;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,7 +103,7 @@ class kolab_driver extends calendar_driver
|
||||||
|
|
||||||
if ($calendar->ready) {
|
if ($calendar->ready) {
|
||||||
$this->calendars[$calendar->id] = $calendar;
|
$this->calendars[$calendar->id] = $calendar;
|
||||||
if ($calendar->writeable)
|
if ($calendar->editable)
|
||||||
$this->has_writeable = true;
|
$this->has_writeable = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -173,7 +173,7 @@ class kolab_driver extends calendar_driver
|
||||||
'owner' => $cal->get_owner(),
|
'owner' => $cal->get_owner(),
|
||||||
'history' => false,
|
'history' => false,
|
||||||
'virtual' => false,
|
'virtual' => false,
|
||||||
'writeable' => false,
|
'editable' => false,
|
||||||
'group' => 'other',
|
'group' => 'other',
|
||||||
'class' => 'user',
|
'class' => 'user',
|
||||||
'removable' => true,
|
'removable' => true,
|
||||||
|
@ -186,7 +186,7 @@ class kolab_driver extends calendar_driver
|
||||||
'listname' => $listname,
|
'listname' => $listname,
|
||||||
'editname' => $cal->get_foldername(),
|
'editname' => $cal->get_foldername(),
|
||||||
'virtual' => true,
|
'virtual' => true,
|
||||||
'writeable' => false,
|
'editable' => false,
|
||||||
'group' => $cal->get_namespace(),
|
'group' => $cal->get_namespace(),
|
||||||
'class' => 'folder',
|
'class' => 'folder',
|
||||||
);
|
);
|
||||||
|
@ -199,8 +199,8 @@ class kolab_driver extends calendar_driver
|
||||||
'editname' => $cal->get_foldername(),
|
'editname' => $cal->get_foldername(),
|
||||||
'title' => $cal->get_title(),
|
'title' => $cal->get_title(),
|
||||||
'color' => $cal->get_color(),
|
'color' => $cal->get_color(),
|
||||||
'writeable' => $cal->writeable,
|
'editable' => $cal->editable,
|
||||||
'insert' => $cal->insert,
|
'rights' => $cal->rights,
|
||||||
'showalarms' => $cal->alarms,
|
'showalarms' => $cal->alarms,
|
||||||
'history' => !empty($this->bonnie_api),
|
'history' => !empty($this->bonnie_api),
|
||||||
'group' => $cal->get_namespace(),
|
'group' => $cal->get_namespace(),
|
||||||
|
@ -233,8 +233,8 @@ class kolab_driver extends calendar_driver
|
||||||
'editname' => $cal->get_foldername(),
|
'editname' => $cal->get_foldername(),
|
||||||
'title' => $cal->get_title(),
|
'title' => $cal->get_title(),
|
||||||
'color' => $cal->get_color(),
|
'color' => $cal->get_color(),
|
||||||
'writeable' => $cal->writeable,
|
'editable' => $cal->editable,
|
||||||
'insert' => $cal->insert,
|
'rights' => $cal->rights,
|
||||||
'showalarms' => $cal->alarms,
|
'showalarms' => $cal->alarms,
|
||||||
'history' => !empty($this->bonnie_api),
|
'history' => !empty($this->bonnie_api),
|
||||||
'group' => 'x-invitations',
|
'group' => 'x-invitations',
|
||||||
|
@ -268,7 +268,7 @@ class kolab_driver extends calendar_driver
|
||||||
'active' => (bool)$prefs[$id]['active'],
|
'active' => (bool)$prefs[$id]['active'],
|
||||||
'showalarms' => (bool)$this->rc->config->get('calendar_birthdays_alarm_type'),
|
'showalarms' => (bool)$this->rc->config->get('calendar_birthdays_alarm_type'),
|
||||||
'group' => 'x-birthdays',
|
'group' => 'x-birthdays',
|
||||||
'writeable' => false,
|
'editable' => false,
|
||||||
'default' => false,
|
'default' => false,
|
||||||
'children' => false,
|
'children' => false,
|
||||||
'history' => false,
|
'history' => false,
|
||||||
|
@ -294,7 +294,7 @@ class kolab_driver extends calendar_driver
|
||||||
'list' => $this->calendars,
|
'list' => $this->calendars,
|
||||||
'calendars' => $calendars,
|
'calendars' => $calendars,
|
||||||
'filter' => $filter,
|
'filter' => $filter,
|
||||||
'writeable' => ($filter & self::FILTER_WRITEABLE),
|
'editable' => ($filter & self::FILTER_WRITEABLE),
|
||||||
'insert' => ($filter & self::FILTER_INSERTABLE),
|
'insert' => ($filter & self::FILTER_INSERTABLE),
|
||||||
'active' => ($filter & self::FILTER_ACTIVE),
|
'active' => ($filter & self::FILTER_ACTIVE),
|
||||||
'personal' => ($filter & self::FILTER_PERSONAL),
|
'personal' => ($filter & self::FILTER_PERSONAL),
|
||||||
|
@ -308,7 +308,7 @@ class kolab_driver extends calendar_driver
|
||||||
if (!$cal->ready) {
|
if (!$cal->ready) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (($filter & self::FILTER_WRITEABLE) && !$cal->writeable) {
|
if (($filter & self::FILTER_WRITEABLE) && !$cal->editable) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (($filter & self::FILTER_INSERTABLE) && !$cal->insert) {
|
if (($filter & self::FILTER_INSERTABLE) && !$cal->insert) {
|
||||||
|
|
|
@ -26,7 +26,8 @@ class kolab_invitation_calendar
|
||||||
public $id = '__invitation__';
|
public $id = '__invitation__';
|
||||||
public $ready = true;
|
public $ready = true;
|
||||||
public $alarms = false;
|
public $alarms = false;
|
||||||
public $writeable = false;
|
public $rights = 'lrsv';
|
||||||
|
public $editable = false;
|
||||||
public $attachments = false;
|
public $attachments = false;
|
||||||
public $subscriptions = false;
|
public $subscriptions = false;
|
||||||
public $partstats = array('unknown');
|
public $partstats = array('unknown');
|
||||||
|
|
|
@ -25,7 +25,7 @@ class kolab_user_calendar extends kolab_calendar
|
||||||
{
|
{
|
||||||
public $id = 'unknown';
|
public $id = 'unknown';
|
||||||
public $ready = false;
|
public $ready = false;
|
||||||
public $writeable = false;
|
public $editable = false;
|
||||||
public $attachments = false;
|
public $attachments = false;
|
||||||
public $subscriptions = false;
|
public $subscriptions = false;
|
||||||
|
|
||||||
|
|
|
@ -294,7 +294,7 @@ class calendar_ui
|
||||||
|
|
||||||
if ($prop['virtual'])
|
if ($prop['virtual'])
|
||||||
$classes[] = 'virtual';
|
$classes[] = 'virtual';
|
||||||
else if (!$prop['writeable'])
|
else if (!$prop['editable'])
|
||||||
$classes[] = 'readonly';
|
$classes[] = 'readonly';
|
||||||
if ($prop['subscribed'])
|
if ($prop['subscribed'])
|
||||||
$classes[] = 'subscribed';
|
$classes[] = 'subscribed';
|
||||||
|
@ -361,7 +361,7 @@ class calendar_ui
|
||||||
$select = new html_select($attrib);
|
$select = new html_select($attrib);
|
||||||
|
|
||||||
foreach ((array)$this->cal->driver->list_calendars() as $id => $prop) {
|
foreach ((array)$this->cal->driver->list_calendars() as $id => $prop) {
|
||||||
if (!empty($prop['insert']))
|
if ($prop['editable'] || strpos($prop['rights'], 'i') !== false)
|
||||||
$select->add($prop['name'], $id);
|
$select->add($prop['name'], $id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue