Render calendar folders as a searchable treelist widget
This commit is contained in:
parent
d2d831b775
commit
00b1c7631b
7 changed files with 283 additions and 114 deletions
|
@ -51,6 +51,7 @@ function rcube_calendar_ui(settings)
|
|||
var ignore_click = false;
|
||||
var event_defaults = { free_busy:'busy', alarms:'' };
|
||||
var event_attendees = [];
|
||||
var calendars_list;
|
||||
var attendees_list;
|
||||
var resources_list;
|
||||
var resources_treelist;
|
||||
|
@ -2658,15 +2659,10 @@ function rcube_calendar_ui(settings)
|
|||
// mark the given calendar folder as selected
|
||||
this.select_calendar = function(id)
|
||||
{
|
||||
var prefix = 'rcmlical';
|
||||
|
||||
$(rcmail.gui_objects.calendarslist).find('li.selected')
|
||||
.removeClass('selected').addClass('unfocused');
|
||||
$('#' + prefix + id, rcmail.gui_objects.calendarslist)
|
||||
.removeClass('unfocused').addClass('selected');
|
||||
calendars_list.select(id);
|
||||
|
||||
// trigger event hook
|
||||
rcmail.triggerEvent('selectfolder', { folder:name, prefix:prefix });
|
||||
rcmail.triggerEvent('selectfolder', { folder:id, prefix:'rcmlical' });
|
||||
|
||||
this.selected_calendar = id;
|
||||
};
|
||||
|
@ -2703,35 +2699,8 @@ function rcube_calendar_ui(settings)
|
|||
event_sources.push(this.calendars[id]);
|
||||
}
|
||||
|
||||
// init event handler on calendar list checkbox
|
||||
if ((li = rcube_find_object('rcmlical' + id))) {
|
||||
$('#'+li.id+' input').click(function(e){
|
||||
var id = $(this).data('id');
|
||||
if (me.calendars[id]) { // add or remove event source on click
|
||||
var action;
|
||||
if (this.checked) {
|
||||
action = 'addEventSource';
|
||||
me.calendars[id].active = true;
|
||||
}
|
||||
else {
|
||||
action = 'removeEventSource';
|
||||
me.calendars[id].active = false;
|
||||
}
|
||||
|
||||
// add/remove event source
|
||||
fc.fullCalendar(action, me.calendars[id]);
|
||||
rcmail.http_post('calendar', { action:'subscribe', c:{ id:id, active:me.calendars[id].active?1:0 } });
|
||||
}
|
||||
}).data('id', id).get(0).checked = active;
|
||||
|
||||
$(li).click(function(e){
|
||||
me.select_calendar($(this).data('id'));
|
||||
rcmail.enable_command('calendar-edit', true);
|
||||
rcmail.enable_command('calendar-remove', 'calendar-showurl', true);
|
||||
})
|
||||
.dblclick(function(){ me.calendar_edit_dialog(me.calendars[me.selected_calendar]); })
|
||||
.data('id', id);
|
||||
}
|
||||
// check active calendars
|
||||
$('#rcmlical'+id+' > .calendar input').data('id', id).get(0).checked = active;
|
||||
|
||||
if (!cal.readonly && !this.selected_calendar) {
|
||||
this.selected_calendar = id;
|
||||
|
@ -2739,6 +2708,49 @@ function rcube_calendar_ui(settings)
|
|||
}
|
||||
}
|
||||
|
||||
// initialize treelist widget that controls the calendars list
|
||||
calendars_list = new rcube_treelist_widget(rcmail.gui_objects.calendarslist, {
|
||||
id_prefix: 'rcmlical',
|
||||
selectable: true,
|
||||
searchbox: '#calendarlistsearch'
|
||||
});
|
||||
calendars_list.addEventListener('select', function(node){
|
||||
me.select_calendar(node.id);
|
||||
rcmail.enable_command('calendar-edit', 'calendar-showurl', true);
|
||||
rcmail.enable_command('calendar-remove', !me.calendars[node.id].readonly);
|
||||
});
|
||||
calendars_list.addEventListener('search', function(search){
|
||||
console.log(search);
|
||||
});
|
||||
|
||||
// init (delegate) event handler on calendar list checkboxes
|
||||
$(rcmail.gui_objects.calendarslist).on('click', 'input[type=checkbox]', function(e){
|
||||
var id = $(this).data('id');
|
||||
if (me.calendars[id]) { // add or remove event source on click
|
||||
var action;
|
||||
if (this.checked) {
|
||||
action = 'addEventSource';
|
||||
me.calendars[id].active = true;
|
||||
}
|
||||
else {
|
||||
action = 'removeEventSource';
|
||||
me.calendars[id].active = false;
|
||||
}
|
||||
|
||||
// add/remove event source
|
||||
fc.fullCalendar(action, me.calendars[id]);
|
||||
rcmail.http_post('calendar', { action:'subscribe', c:{ id:id, active:me.calendars[id].active?1:0 } });
|
||||
|
||||
e.stopPropagation();
|
||||
}
|
||||
});
|
||||
|
||||
// register dbl-click handler to open calendar edit dialog
|
||||
$(rcmail.gui_objects.calendarslist).on('dblclick', ':not(.virtual) > .calname', function(e){
|
||||
var id = $(this).closest('li').attr('id').replace(/^rcmlical/, '');
|
||||
me.calendar_edit_dialog(me.calendars[id]);
|
||||
});
|
||||
|
||||
// select default calendar
|
||||
if (settings.default_calendar && this.calendars[settings.default_calendar] && !this.calendars[settings.default_calendar].readonly)
|
||||
this.selected_calendar = settings.default_calendar;
|
||||
|
|
|
@ -88,16 +88,16 @@ class kolab_driver extends calendar_driver
|
|||
return $this->calendars;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a list of available calendars from this source
|
||||
*
|
||||
* @param bool $active Return only active calendars
|
||||
* @param bool $personal Return only personal calendars
|
||||
* @param object $tree Reference to hierarchical folder tree object
|
||||
*
|
||||
* @return array List of calendars
|
||||
*/
|
||||
public function list_calendars($active = false, $personal = false)
|
||||
public function list_calendars($active = false, $personal = false, &$tree = null)
|
||||
{
|
||||
// attempt to create a default calendar for this user
|
||||
if (!$this->has_writeable) {
|
||||
|
@ -112,7 +112,7 @@ class kolab_driver extends calendar_driver
|
|||
|
||||
// include virtual folders for a full folder tree
|
||||
if (!$active && !$personal && !$this->rc->output->ajax_call && in_array($this->rc->action, array('index','')))
|
||||
$folders = kolab_storage::folder_hierarchy($folders);
|
||||
$folders = kolab_storage::folder_hierarchy($folders, $tree);
|
||||
|
||||
foreach ($folders as $id => $cal) {
|
||||
$fullname = $cal->get_name();
|
||||
|
@ -124,6 +124,7 @@ class kolab_driver extends calendar_driver
|
|||
'id' => $cal->id,
|
||||
'name' => $fullname,
|
||||
'listname' => $listname,
|
||||
'editname' => $cal->get_foldername(),
|
||||
'virtual' => true,
|
||||
'readonly' => true,
|
||||
);
|
||||
|
@ -1106,6 +1107,11 @@ class kolab_driver extends calendar_driver
|
|||
*/
|
||||
public function calendar_form($action, $calendar, $formfields)
|
||||
{
|
||||
// show default dialog for birthday calendar
|
||||
if ($calendar['id'] == self::BIRTHDAY_CALENDAR_ID) {
|
||||
return parent::calendar_form($action, $calendar, $formfields);
|
||||
}
|
||||
|
||||
if ($calendar['id'] && ($cal = $this->calendars[$calendar['id']])) {
|
||||
$folder = $cal->get_realname(); // UTF7
|
||||
$color = $cal->get_color();
|
||||
|
|
|
@ -187,45 +187,108 @@ class calendar_ui
|
|||
*/
|
||||
function calendar_list($attrib = array())
|
||||
{
|
||||
$calendars = $this->cal->driver->list_calendars();
|
||||
$html = '';
|
||||
$jsenv = array();
|
||||
$calendars = $this->cal->driver->list_calendars(false, false, $tree);
|
||||
|
||||
// walk folder tree
|
||||
if (is_object($tree)) {
|
||||
$html = $this->list_tree_html($tree, $calendars, $jsenv, $attrib);
|
||||
|
||||
// append birthdays calendar which isn't part of $tree
|
||||
if ($bdaycal = $calendars[calendar_driver::BIRTHDAY_CALENDAR_ID]) {
|
||||
$calendars = array(calendar_driver::BIRTHDAY_CALENDAR_ID => $bdaycal);
|
||||
}
|
||||
else {
|
||||
$calendars = array(); // clear array for flat listing
|
||||
}
|
||||
}
|
||||
else {
|
||||
// fall-back to flat folder listing
|
||||
$attrib['class'] .= ' flat';
|
||||
}
|
||||
|
||||
$li = '';
|
||||
foreach ((array)$calendars as $id => $prop) {
|
||||
if ($attrib['activeonly'] && !$prop['active'])
|
||||
continue;
|
||||
|
||||
unset($prop['user_id']);
|
||||
$prop['alarms'] = $this->cal->driver->alarms;
|
||||
$prop['attendees'] = $this->cal->driver->attendees;
|
||||
$prop['freebusy'] = $this->cal->driver->freebusy;
|
||||
$prop['attachments'] = $this->cal->driver->attachments;
|
||||
$prop['undelete'] = $this->cal->driver->undelete;
|
||||
$prop['feedurl'] = $this->cal->get_url(array('_cal' => $this->cal->ical_feed_hash($id) . '.ics', 'action' => 'feed'));
|
||||
|
||||
if (!$prop['virtual'])
|
||||
$jsenv[$id] = $prop;
|
||||
|
||||
$html_id = html_identifier($id);
|
||||
$class = 'cal-' . asciiwords($id, true);
|
||||
$title = $prop['name'] != $prop['listname'] ? html_entity_decode($prop['name'], ENT_COMPAT, RCMAIL_CHARSET) : '';
|
||||
|
||||
if ($prop['virtual'])
|
||||
$class .= ' virtual';
|
||||
else if ($prop['readonly'])
|
||||
$class .= ' readonly';
|
||||
if ($prop['class_name'])
|
||||
$class .= ' '.$prop['class_name'];
|
||||
|
||||
$li .= html::tag('li', array('id' => 'rcmlical' . $html_id, 'class' => $class),
|
||||
($prop['virtual'] ? '' : html::tag('input', array('type' => 'checkbox', 'name' => '_cal[]', 'value' => $id, 'checked' => $prop['active']), '') .
|
||||
html::span('handle', ' ')) .
|
||||
html::span(array('class' => 'calname', 'title' => $title), $prop['listname']));
|
||||
$html .= html::tag('li', array('id' => 'rcmlical' . rcube_utils::html_identifier($id)),
|
||||
$content = $this->calendar_list_item($id, $prop, $jsenv)
|
||||
);
|
||||
}
|
||||
|
||||
$this->rc->output->set_env('calendars', $jsenv);
|
||||
$this->rc->output->add_gui_object('calendarslist', $attrib['id']);
|
||||
|
||||
return html::tag('ul', $attrib, $li, html::$common_attrib);
|
||||
return html::tag('ul', $attrib, $html, html::$common_attrib);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return html for a structured list <ul> for the mailbox tree
|
||||
*/
|
||||
public function list_tree_html(&$node, &$data, &$jsenv, $attrib)
|
||||
{
|
||||
$out = '';
|
||||
foreach ($node->children as $folder) {
|
||||
$id = $folder->id;
|
||||
$prop = $data[$id];
|
||||
|
||||
$content = $this->calendar_list_item($id, $prop, $jsenv);
|
||||
|
||||
if (!empty($folder->children)) {
|
||||
$content .= html::tag('ul', array('style' => ($is_collapsed ? "display:none;" : null)),
|
||||
$this->list_tree_html($folder, $data, $jsenv, $attrib));
|
||||
}
|
||||
|
||||
if (strlen($content)) {
|
||||
$out .= html::tag('li', array(
|
||||
'id' => 'rcmlical' . rcube_utils::html_identifier($id),
|
||||
'class' => $prop['virtual'] ? 'virtual' : '',
|
||||
),
|
||||
$content);
|
||||
}
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to build a calendar list item (HTML content and js data)
|
||||
*/
|
||||
protected function calendar_list_item($id, $prop, &$jsenv)
|
||||
{
|
||||
unset($prop['user_id']);
|
||||
$prop['alarms'] = $this->cal->driver->alarms;
|
||||
$prop['attendees'] = $this->cal->driver->attendees;
|
||||
$prop['freebusy'] = $this->cal->driver->freebusy;
|
||||
$prop['attachments'] = $this->cal->driver->attachments;
|
||||
$prop['undelete'] = $this->cal->driver->undelete;
|
||||
$prop['feedurl'] = $this->cal->get_url(array('_cal' => $this->cal->ical_feed_hash($id) . '.ics', 'action' => 'feed'));
|
||||
|
||||
if (!$prop['virtual'])
|
||||
$jsenv[$id] = $prop;
|
||||
|
||||
$class = 'calendar cal-' . asciiwords($id, true);
|
||||
$title = $prop['name'] != $prop['listname'] ? html_entity_decode($prop['name'], ENT_COMPAT, RCMAIL_CHARSET) : '';
|
||||
$is_collapsed = false; // TODO: determine this somehow?
|
||||
|
||||
if ($prop['virtual'])
|
||||
$class = 'folder virtual';
|
||||
else if ($prop['readonly'])
|
||||
$class .= ' readonly';
|
||||
if ($prop['class_name'])
|
||||
$class .= ' '.$prop['class_name'];
|
||||
|
||||
$content = '';
|
||||
if (!$attrib['activeonly'] || $prop['active']) {
|
||||
$content = html::div($class,
|
||||
($prop['virtual'] ? '' : html::tag('input', array('type' => 'checkbox', 'name' => '_cal[]', 'value' => $id, 'checked' => $prop['active']), '') .
|
||||
html::span('handle', ' ')) .
|
||||
html::span(array('class' => 'calname', 'title' => $title), $prop['editname'] ? Q($prop['editname']) : $prop['listname'])
|
||||
);
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -164,45 +164,64 @@ pre {
|
|||
right: 0;
|
||||
}
|
||||
|
||||
#calendarslist li {
|
||||
margin: 0;
|
||||
height: 20px;
|
||||
padding: 6px 8px 2px;
|
||||
display: block;
|
||||
position: relative;
|
||||
#calendars .scroller {
|
||||
top: 68px;
|
||||
}
|
||||
|
||||
#calendarslist li.virtual {
|
||||
height: 12px;
|
||||
#calendarslist li {
|
||||
margin: 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#calendarslist li label {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#calendarslist li div.folder,
|
||||
#calendarslist li div.calendar {
|
||||
position: relative;
|
||||
height: 28px;
|
||||
}
|
||||
|
||||
#calendarslist li div.virtual {
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
|
||||
#calendarslist li span.calname {
|
||||
display: block;
|
||||
padding: 0px 30px 2px 2px;
|
||||
position: absolute;
|
||||
top: 6px;
|
||||
left: 26px;
|
||||
right: 24px;
|
||||
top: 7px;
|
||||
left: 38px;
|
||||
right: 22px;
|
||||
cursor: default;
|
||||
background: url(images/calendars.png) right 20px no-repeat;
|
||||
padding-bottom: 2px;
|
||||
padding-right: 30px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
color: #004458;
|
||||
}
|
||||
|
||||
#calendarslist li div.virtual > span.calname {
|
||||
color: #aaa;
|
||||
top: 4px;
|
||||
left: 20px;
|
||||
}
|
||||
|
||||
#calendarslist.flat li span.calname {
|
||||
left: 24px;
|
||||
}
|
||||
|
||||
#calendarslist li span.handle {
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: 6px;
|
||||
padding: 0;
|
||||
border-radius: 7px;
|
||||
margin-right: 6px;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 7px;
|
||||
font-size: 0.8em;
|
||||
border: 1px solid rgba(0, 0, 0, 0.5);
|
||||
-webkit-box-shadow: inset 0px 0 1px 1px rgba(0, 0, 0, 0.3);
|
||||
|
@ -212,43 +231,65 @@ pre {
|
|||
|
||||
#calendarslist li input {
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
right: 5px;
|
||||
top: 5px;
|
||||
left: 18px;
|
||||
}
|
||||
|
||||
#calendarslist li div.treetoggle {
|
||||
top: 8px;
|
||||
}
|
||||
|
||||
#calendarslist li.virtual div.treetoggle {
|
||||
top: 6px;
|
||||
}
|
||||
|
||||
#calendarslist.flat li input {
|
||||
left: 4px;
|
||||
}
|
||||
|
||||
#calendarslist ul li div.folder,
|
||||
#calendarslist ul li div.calendar {
|
||||
margin-left: 16px;
|
||||
}
|
||||
|
||||
#calendarslist ul ul li div.folder,
|
||||
#calendarslist ul ul li div.calendar {
|
||||
margin-left: 32px;
|
||||
}
|
||||
|
||||
#calendarslist ul ul ul li div.folder,
|
||||
#calendarslist ul ul ul li div.calendar {
|
||||
margin-left: 48px;
|
||||
}
|
||||
|
||||
#calendarslist li.selected {
|
||||
background-color: #c7e3ef;
|
||||
}
|
||||
|
||||
#calendarslist li.selected span.calname {
|
||||
#calendarslist li.selected > span.calname {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#calendarslist li.readonly span.calname {
|
||||
#calendarslist div.readonly span.calname {
|
||||
background-position: right -20px;
|
||||
}
|
||||
|
||||
#calendarslist li.other span.calname {
|
||||
#calendarslist div.other span.calname {
|
||||
background-position: right -38px;
|
||||
}
|
||||
|
||||
#calendarslist li.other.readonly span.calname {
|
||||
#calendarslist div.other.readonly span.calname {
|
||||
background-position: right -56px;
|
||||
}
|
||||
|
||||
#calendarslist li.shared span.calname {
|
||||
#calendarslist div.shared span.calname {
|
||||
background-position: right -74px;
|
||||
}
|
||||
|
||||
#calendarslist li.shared.readonly span.calname {
|
||||
#calendarslist div.shared.readonly span.calname {
|
||||
background-position: right -92px;
|
||||
}
|
||||
|
||||
#calendarslist li.virtual span.calname {
|
||||
color: #aaa;
|
||||
top: 2px;
|
||||
}
|
||||
|
||||
#calfeedurl,
|
||||
#caldavurl {
|
||||
width: 98%;
|
||||
|
|
|
@ -23,8 +23,15 @@
|
|||
|
||||
<div id="calendars" class="uibox listbox" style="visibility:hidden">
|
||||
<h2 class="boxtitle"><roundcube:label name="calendar.calendars" /></h2>
|
||||
<div class="listsearchbox">
|
||||
<div class="searchbox">
|
||||
<input type="text" name="q" id="calendarlistsearch" />
|
||||
<a class="iconbutton searchicon"></a>
|
||||
<roundcube:button command="reset-listsearch" id="calendarlistsearch-reset" class="iconbutton reset" title="resetsearch" content="x" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="scroller withfooter">
|
||||
<roundcube:object name="plugin.calendar_list" id="calendarslist" class="listing" />
|
||||
<roundcube:object name="plugin.calendar_list" id="calendarslist" class="treelist listing" />
|
||||
</div>
|
||||
<div class="boxfooter">
|
||||
<roundcube:button command="calendar-create" type="link" title="calendar.createcalendar" class="listbutton add disabled" classAct="listbutton add" innerClass="inner" content="+" /><roundcube:button name="calendaroptionslink" id="calendaroptionsmenulink" type="link" title="moreactions" class="listbutton groupactions" onclick="UI.show_popup('calendaroptionsmenu', undefined, { above:true });return false" innerClass="inner" content="⚙" />
|
||||
|
|
|
@ -756,43 +756,54 @@ class kolab_storage
|
|||
* Check the folder tree and add the missing parents as virtual folders
|
||||
*
|
||||
* @param array $folders Folders list
|
||||
* @param object $tree Reference to the root node of the folder tree
|
||||
*
|
||||
* @return array Folders list
|
||||
* @return array Flat folders list
|
||||
*/
|
||||
public static function folder_hierarchy($folders)
|
||||
public static function folder_hierarchy($folders, &$tree)
|
||||
{
|
||||
$_folders = array();
|
||||
$existing = array_map(function($folder){ return $folder->get_name(); }, $folders);
|
||||
$delim = rcube::get_instance()->get_storage()->get_hierarchy_delimiter();
|
||||
$tree = new virtual_kolab_storage_folder('', '<root>', ''); // create tree root
|
||||
$refs = array('' => $tree);
|
||||
|
||||
foreach ($folders as $idx => $folder) {
|
||||
$path = explode($delim, $folder->name);
|
||||
array_pop($path);
|
||||
$folder->parent = join($delim, $path);
|
||||
$folder->children = array(); // reset list
|
||||
|
||||
// skip top folders or ones with a custom displayname
|
||||
if (count($path) <= 1 || kolab_storage::custom_displayname($folder->name)) {
|
||||
if (count($path) < 1 || kolab_storage::custom_displayname($folder->name)) {
|
||||
$tree->children[] = $folder;
|
||||
}
|
||||
else {
|
||||
$parents = array();
|
||||
$depth = $folder->get_namespace() == 'personal' ? 1 : 2;
|
||||
|
||||
while (count($path) > 1 && ($parent = join($delim, $path))) {
|
||||
$name = kolab_storage::object_name($parent, $folder->get_namespace());
|
||||
if (!in_array($name, $existing)) {
|
||||
$parents[$parent] = new virtual_kolab_storage_folder($parent, $name, $folder->get_namespace());
|
||||
$existing[] = $name;
|
||||
}
|
||||
|
||||
while (count($path) >= $depth && ($parent = join($delim, $path))) {
|
||||
array_pop($path);
|
||||
$name = kolab_storage::object_name($parent, $folder->get_namespace());
|
||||
if (!$refs[$parent]) {
|
||||
$refs[$parent] = new virtual_kolab_storage_folder($parent, $name, $folder->get_namespace(), join($delim, $path));
|
||||
$parents[] = $refs[$parent];
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($parents)) {
|
||||
$parents = array_reverse(array_values($parents));
|
||||
$parents = array_reverse($parents);
|
||||
foreach ($parents as $parent) {
|
||||
$parent_node = $refs[$parent->parent] ?: $tree;
|
||||
$parent_node->children[] = $parent;
|
||||
$_folders[] = $parent;
|
||||
}
|
||||
}
|
||||
|
||||
$parent_node = $refs[$folder->parent] ?: $tree;
|
||||
$parent_node->children[] = $folder;
|
||||
}
|
||||
|
||||
$refs[$folder->name] = $folder;
|
||||
$_folders[] = $folder;
|
||||
unset($folders[$idx]);
|
||||
}
|
||||
|
@ -1164,13 +1175,18 @@ class virtual_kolab_storage_folder
|
|||
public $id;
|
||||
public $name;
|
||||
public $namespace;
|
||||
public $parent = '';
|
||||
public $children = array();
|
||||
public $virtual = true;
|
||||
protected $displayname;
|
||||
|
||||
public function __construct($realname, $name, $ns)
|
||||
public function __construct($name, $dispname, $ns, $parent = '')
|
||||
{
|
||||
$this->id = kolab_storage::folder_id($realname);
|
||||
$this->id = kolab_storage::folder_id($name);
|
||||
$this->name = $name;
|
||||
$this->namespace = $ns;
|
||||
$this->parent = $parent;
|
||||
$this->displayname = $dispname;
|
||||
}
|
||||
|
||||
public function get_namespace()
|
||||
|
@ -1181,6 +1197,12 @@ class virtual_kolab_storage_folder
|
|||
public function get_name()
|
||||
{
|
||||
// this is already kolab_storage::object_name() result
|
||||
return $this->name;
|
||||
return $this->displayname;
|
||||
}
|
||||
|
||||
public function get_foldername()
|
||||
{
|
||||
$parts = explode('/', $this->name);
|
||||
return rcube_charset::convert(end($parts), 'UTF7-IMAP');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,6 +48,12 @@ class kolab_storage_folder
|
|||
*/
|
||||
public $cache;
|
||||
|
||||
/**
|
||||
* List of direct child folders
|
||||
* @var array
|
||||
*/
|
||||
public $children = array();
|
||||
|
||||
private $type_annotation;
|
||||
private $namespace;
|
||||
private $imap;
|
||||
|
@ -217,6 +223,18 @@ class kolab_storage_folder
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Getter for the top-end folder name (not the entire path)
|
||||
*
|
||||
* @return string Name of this folder
|
||||
*/
|
||||
public function get_foldername()
|
||||
{
|
||||
$parts = explode('/', $this->name);
|
||||
return rcube_charset::convert(end($parts), 'UTF7-IMAP');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the color value stored in metadata
|
||||
*
|
||||
|
|
Loading…
Add table
Reference in a new issue