Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F10703871
folders.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
15 KB
Referenced Files
None
Subscribers
None
folders.php
View Options
<?php
/**
+-----------------------------------------------------------------------+
| This file is part of the Roundcube Webmail client |
| |
| Copyright (C) The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
| See the README file for a full license statement. |
| |
| PURPOSE: |
| Provide functionality of folders listing |
+-----------------------------------------------------------------------+
| Author: Thomas Bruederli <roundcube@gmail.com> |
| Author: Aleksander Machniak <alec@alec.pl> |
+-----------------------------------------------------------------------+
*/
class
rcmail_action_settings_folders
extends
rcmail_action_settings_index
{
protected
static
$mode
=
self
::
MODE_HTTP
;
/**
* Request handler.
*
* @param array $args Arguments from the previous step(s)
*/
public
function
run
(
$args
=
[])
{
$rcmail
=
rcmail
::
get_instance
();
$storage
=
$rcmail
->
get_storage
();
$rcmail
->
output
->
set_pagetitle
(
$rcmail
->
gettext
(
'folders'
));
$rcmail
->
output
->
set_env
(
'prefix_ns'
,
$storage
->
get_namespace
(
'prefix'
));
$rcmail
->
output
->
set_env
(
'quota'
,
(
bool
)
$storage
->
get_capability
(
'QUOTA'
));
$rcmail
->
output
->
include_script
(
'treelist.js'
);
// add some labels to client
$rcmail
->
output
->
add_label
(
'deletefolderconfirm'
,
'purgefolderconfirm'
,
'movefolderconfirm'
,
'folderdeleting'
,
'foldermoving'
,
'foldersubscribing'
,
'folderunsubscribing'
,
'move'
,
'quota'
);
// register UI objects
$rcmail
->
output
->
add_handlers
([
'foldersubscription'
=>
[
$this
,
'folder_subscriptions'
],
'folderfilter'
=>
[
$this
,
'folder_filter'
],
'quotadisplay'
=>
[
$rcmail
,
'quota_display'
],
'searchform'
=>
[
$rcmail
->
output
,
'search_form'
],
]);
$rcmail
->
output
->
send
(
'folders'
);
}
// build table with all folders listed by server
public
static
function
folder_subscriptions
(
$attrib
)
{
$rcmail
=
rcmail
::
get_instance
();
$storage
=
$rcmail
->
get_storage
();
if
(
empty
(
$attrib
[
'id'
]))
{
$attrib
[
'id'
]
=
'rcmSubscriptionlist'
;
}
// get folders from server
$storage
->
clear_cache
(
'mailboxes'
,
true
);
$a_unsubscribed
=
$storage
->
list_folders
();
$a_subscribed
=
$storage
->
list_folders_subscribed
(
''
,
'*'
,
null
,
null
,
true
);
// unsorted
$delimiter
=
$storage
->
get_hierarchy_delimiter
();
$namespace
=
$storage
->
get_namespace
();
$special_folders
=
array_flip
(
array_merge
([
'inbox'
=>
'INBOX'
],
$storage
->
get_special_folders
()));
$protect_default
=
$rcmail
->
config
->
get
(
'protect_default_folders'
);
$seen
=
[];
$list_folders
=
[];
// pre-process folders list
foreach
(
$a_unsubscribed
as
$i
=>
$folder
)
{
$folder_id
=
$folder
;
$folder
=
$storage
->
mod_folder
(
$folder
);
$foldersplit
=
explode
(
$delimiter
,
$folder
);
$name
=
rcube_charset
::
convert
(
array_pop
(
$foldersplit
),
'UTF7-IMAP'
);
$is_special
=
isset
(
$special_folders
[
$folder_id
]);
$parent_folder
=
$is_special
?
''
:
join
(
$delimiter
,
$foldersplit
);
$level
=
$is_special
?
0
:
count
(
$foldersplit
);
// add any necessary "virtual" parent folders
if
(
$parent_folder
&&
empty
(
$seen
[
$parent_folder
]))
{
for
(
$i
=
1
;
$i
<=
$level
;
$i
++)
{
$ancestor_folder
=
join
(
$delimiter
,
array_slice
(
$foldersplit
,
0
,
$i
));
if
(
$ancestor_folder
)
{
if
(
empty
(
$seen
[
$ancestor_folder
]))
{
$seen
[
$ancestor_folder
]
=
true
;
$ancestor_name
=
rcube_charset
::
convert
(
$foldersplit
[
$i
-
1
],
'UTF7-IMAP'
);
$list_folders
[]
=
[
'id'
=>
$ancestor_folder
,
'name'
=>
$ancestor_name
,
'level'
=>
$i
-
1
,
'virtual'
=>
true
,
];
}
}
}
}
// Handle properly INBOX.INBOX situation
if
(
isset
(
$seen
[
$folder
]))
{
continue
;
}
$seen
[
$folder
]
=
true
;
$list_folders
[]
=
[
'id'
=>
$folder_id
,
'name'
=>
$name
,
'level'
=>
$level
,
];
}
unset
(
$seen
);
$checkbox_subscribe
=
new
html_checkbox
([
'name'
=>
'_subscribed[]'
,
'title'
=>
$rcmail
->
gettext
(
'changesubscription'
),
'onclick'
=>
rcmail_output
::
JS_OBJECT_NAME
.
".command(this.checked?'subscribe':'unsubscribe',this.value)"
,
]);
$js_folders
=
[];
$folders
=
[];
$collapsed
=
(
string
)
$rcmail
->
config
->
get
(
'collapsed_folders'
);
// create list of available folders
foreach
(
$list_folders
as
$i
=>
$folder
)
{
$sub_key
=
array_search
(
$folder
[
'id'
],
$a_subscribed
);
$is_subscribed
=
$sub_key
!==
false
;
$is_special
=
isset
(
$special_folders
[
$folder
[
'id'
]]);
$is_protected
=
$folder
[
'id'
]
==
'INBOX'
||
(
$protect_default
&&
$is_special
);
$noselect
=
false
;
$classes
=
[];
$folder_utf8
=
rcube_charset
::
convert
(
$folder
[
'id'
],
'UTF7-IMAP'
);
$display_folder
=
rcube
::
Q
(
$is_special
?
self
::
localize_foldername
(
$folder
[
'id'
],
false
,
true
)
:
$folder
[
'name'
]);
if
(!
empty
(
$folder
[
'virtual'
]))
{
$classes
[]
=
'virtual'
;
}
// Check \Noselect flag (of existing folder)
if
(!
$is_protected
&&
in_array
(
$folder
[
'id'
],
$a_unsubscribed
))
{
$attrs
=
$storage
->
folder_attributes
(
$folder
[
'id'
]);
$noselect
=
in_array_nocase
(
'
\\
Noselect'
,
$attrs
);
}
$is_disabled
=
((
$is_protected
&&
$is_subscribed
)
||
$noselect
);
// Below we will disable subscription option for "virtual" folders
// according to namespaces, but only if they aren't already subscribed.
// User should be able to unsubscribe from the folder
// even if it doesn't exists or is not accessible (OTRS:1000059)
if
(!
$is_subscribed
&&
!
$is_disabled
&&
!
empty
(
$namespace
)
&&
!
empty
(
$folder
[
'virtual'
]))
{
// check if the folder is a namespace prefix, then disable subscription option on it
if
(!
$is_disabled
&&
$folder
[
'level'
]
==
0
)
{
$fname
=
$folder
[
'id'
]
.
$delimiter
;
foreach
(
$namespace
as
$ns
)
{
if
(
is_array
(
$ns
))
{
foreach
(
$ns
as
$item
)
{
if
(
$item
[
0
]
===
$fname
)
{
$is_disabled
=
true
;
break
2
;
}
}
}
}
}
// check if the folder is an other users virtual-root folder, then disable subscription option on it
if
(!
$is_disabled
&&
$folder
[
'level'
]
==
1
&&
!
empty
(
$namespace
[
'other'
]))
{
$parts
=
explode
(
$delimiter
,
$folder
[
'id'
]);
$fname
=
$parts
[
0
]
.
$delimiter
;
foreach
(
$namespace
[
'other'
]
as
$item
)
{
if
(
$item
[
0
]
===
$fname
)
{
$is_disabled
=
true
;
break
;
}
}
}
// check if the folder is shared, then disable subscription option on it (if not subscribed already)
if
(!
$is_disabled
)
{
$tmp_ns
=
array_merge
((
array
)
$namespace
[
'other'
],
(
array
)
$namespace
[
'shared'
]);
foreach
(
$tmp_ns
as
$item
)
{
if
(
strlen
(
$item
[
0
])
&&
strpos
(
$folder
[
'id'
],
$item
[
0
])
===
0
)
{
$is_disabled
=
true
;
break
;
}
}
}
}
$is_collapsed
=
strpos
(
$collapsed
,
'&'
.
rawurlencode
(
$folder
[
'id'
]).
'&'
)
!==
false
;
$folder_id
=
rcube_utils
::
html_identifier
(
$folder
[
'id'
],
true
);
if
(
$folder_class
=
self
::
folder_classname
(
$folder
[
'id'
]))
{
$classes
[]
=
$folder_class
;
}
$folders
[
$folder
[
'id'
]]
=
[
'idx'
=>
$folder_id
,
'folder_imap'
=>
$folder
[
'id'
],
'folder'
=>
$folder_utf8
,
'display'
=>
$display_folder
,
'protected'
=>
$is_protected
||
!
empty
(
$folder
[
'virtual'
]),
'class'
=>
join
(
' '
,
$classes
),
'subscribed'
=>
$is_subscribed
,
'level'
=>
$folder
[
'level'
],
'collapsed'
=>
$is_collapsed
,
'content'
=>
html
::
a
([
'href'
=>
'#'
],
$display_folder
)
.
$checkbox_subscribe
->
show
((
$is_subscribed
?
$folder
[
'id'
]
:
''
),
[
'value'
=>
$folder
[
'id'
],
'disabled'
=>
$is_disabled
?
'disabled'
:
''
])
];
}
$plugin
=
$rcmail
->
plugins
->
exec_hook
(
'folders_list'
,
[
'list'
=>
$folders
]);
// add drop-target representing 'root'
$root
=
[
'idx'
=>
rcube_utils
::
html_identifier
(
'*'
,
true
),
'folder_imap'
=>
'*'
,
'folder'
=>
''
,
'display'
=>
''
,
'protected'
=>
true
,
'class'
=>
'root'
,
'content'
=>
'<span> </span>'
,
];
$folders
=
[];
$plugin
[
'list'
]
=
array_values
(
$plugin
[
'list'
]);
array_unshift
(
$plugin
[
'list'
],
$root
);
for
(
$i
=
0
,
$length
=
count
(
$plugin
[
'list'
]);
$i
<
$length
;
$i
++)
{
$folders
[]
=
self
::
folder_tree_element
(
$plugin
[
'list'
],
$i
,
$js_folders
);
}
$rcmail
->
output
->
add_gui_object
(
'subscriptionlist'
,
$attrib
[
'id'
]);
$rcmail
->
output
->
set_env
(
'subscriptionrows'
,
$js_folders
);
$rcmail
->
output
->
set_env
(
'defaultfolders'
,
array_keys
(
$special_folders
));
$rcmail
->
output
->
set_env
(
'collapsed_folders'
,
$collapsed
);
$rcmail
->
output
->
set_env
(
'delimiter'
,
$delimiter
);
return
html
::
tag
(
'ul'
,
$attrib
,
implode
(
''
,
$folders
),
html
::
$common_attrib
);
}
public
static
function
folder_tree_element
(
$folders
,
&
$key
,
&
$js_folders
)
{
$data
=
$folders
[
$key
];
$idx
=
'rcmli'
.
$data
[
'idx'
];
$js_folders
[
$data
[
'folder_imap'
]]
=
[
$data
[
'folder'
],
$data
[
'display'
],
$data
[
'protected'
]];
$content
=
$data
[
'content'
];
$attribs
=
[
'id'
=>
$idx
,
'class'
=>
trim
(
$data
[
'class'
]
.
' mailbox'
)
];
if
(!
isset
(
$data
[
'level'
]))
{
$data
[
'level'
]
=
0
;
}
$children
=
[];
while
(!
empty
(
$folders
[
$key
+
1
])
&&
(
$folders
[
$key
+
1
][
'level'
]
>
$data
[
'level'
]))
{
$key
++;
$children
[]
=
self
::
folder_tree_element
(
$folders
,
$key
,
$js_folders
);
}
if
(!
empty
(
$children
))
{
$content
.=
html
::
div
(
'treetoggle '
.
(!
empty
(
$data
[
'collapsed'
])
?
'collapsed'
:
'expanded'
),
' '
)
.
html
::
tag
(
'ul'
,
[
'style'
=>
!
empty
(
$data
[
'collapsed'
])
?
"display:none"
:
null
],
implode
(
"
\n
"
,
$children
));
}
return
html
::
tag
(
'li'
,
$attribs
,
$content
);
}
public
static
function
folder_filter
(
$attrib
)
{
$rcmail
=
rcmail
::
get_instance
();
$storage
=
$rcmail
->
get_storage
();
$namespace
=
$storage
->
get_namespace
();
if
(
empty
(
$namespace
[
'personal'
])
&&
empty
(
$namespace
[
'shared'
])
&&
empty
(
$namespace
[
'other'
]))
{
return
''
;
}
if
(
empty
(
$attrib
[
'id'
]))
{
$attrib
[
'id'
]
=
'rcmfolderfilter'
;
}
if
(!
self
::
get_bool_attr
(
$attrib
,
'noevent'
))
{
$attrib
[
'onchange'
]
=
rcmail_output
::
JS_OBJECT_NAME
.
'.folder_filter(this.value)'
;
}
$roots
=
[];
$select
=
new
html_select
(
$attrib
);
$select
->
add
(
$rcmail
->
gettext
(
'all'
),
'---'
);
foreach
(
array_keys
(
$namespace
)
as
$type
)
{
foreach
((
array
)
$namespace
[
$type
]
as
$ns
)
{
$root
=
rtrim
(
$ns
[
0
],
$ns
[
1
]);
$label
=
$rcmail
->
gettext
(
'namespace.'
.
$type
);
if
(
count
(
$namespace
[
$type
])
>
1
)
{
$label
.=
' ('
.
rcube_charset
::
convert
(
$root
,
'UTF7-IMAP'
,
RCUBE_CHARSET
)
.
')'
;
}
$select
->
add
(
$label
,
$root
);
if
(
strlen
(
$root
))
{
$roots
[]
=
$root
;
}
}
}
$rcmail
->
output
->
add_gui_object
(
'foldersfilter'
,
$attrib
[
'id'
]);
$rcmail
->
output
->
set_env
(
'ns_roots'
,
$roots
);
return
$select
->
show
();
}
public
static
function
folder_options
(
$mailbox
)
{
$rcmail
=
rcmail
::
get_instance
();
$options
=
$rcmail
->
get_storage
()->
folder_info
(
$mailbox
);
$options
[
'protected'
]
=
!
empty
(
$options
[
'is_root'
])
||
strtoupper
(
$mailbox
)
===
'INBOX'
||
(!
empty
(
$options
[
'special'
])
&&
$rcmail
->
config
->
get
(
'protect_default_folders'
));
return
$options
;
}
/**
* Updates (or creates) folder row in the subscriptions table
*
* @param string $name Folder name
* @param string $oldname Old folder name (for update)
* @param bool $subscribe Checks subscription checkbox
* @param string $class CSS class name for folder row
*/
public
static
function
update_folder_row
(
$name
,
$oldname
=
null
,
$subscribe
=
false
,
$class_name
=
null
)
{
$rcmail
=
rcmail
::
get_instance
();
$storage
=
$rcmail
->
get_storage
();
$delimiter
=
$storage
->
get_hierarchy_delimiter
();
$options
=
self
::
folder_options
(
$name
);
$name_utf8
=
rcube_charset
::
convert
(
$name
,
'UTF7-IMAP'
);
$foldersplit
=
explode
(
$delimiter
,
$storage
->
mod_folder
(
$name
));
$level
=
count
(
$foldersplit
)
-
1
;
$class_name
=
trim
(
$class_name
.
' mailbox'
);
if
(!
empty
(
$options
[
'protected'
]))
{
$display_name
=
self
::
localize_foldername
(
$name
);
}
else
{
$display_name
=
rcube_charset
::
convert
(
$foldersplit
[
$level
],
'UTF7-IMAP'
);
}
$protected
=
!
empty
(
$options
[
'protected'
])
||
!
empty
(
$options
[
'noselect'
]);
if
(
$oldname
===
null
)
{
$rcmail
->
output
->
command
(
'add_folder_row'
,
$name
,
$name_utf8
,
$display_name
,
$protected
,
$subscribe
,
$class_name
);
}
else
{
$rcmail
->
output
->
command
(
'replace_folder_row'
,
$oldname
,
$name
,
$name_utf8
,
$display_name
,
$protected
,
$class_name
);
}
}
}
File Metadata
Details
Attached
Mime Type
text/x-php
Expires
Mon, Sep 7, 12:09 PM (1 d, 1 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1349716
Default Alt Text
folders.php (15 KB)
Attached To
Mode
R3 roundcubemail
Attached
Detach File
Event Timeline
Log In to Comment