Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F117752156
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
16 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/program/actions/settings/folders.php b/program/actions/settings/folders.php
index 5316eb09e..93af59303 100644
--- a/program/actions/settings/folders.php
+++ b/program/actions/settings/folders.php
@@ -1,377 +1,377 @@
<?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);
+ $parent_folder = join($delimiter, $foldersplit);
+ $level = 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_name 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-diff
Expires
Sat, Apr 4, 3:48 AM (1 d, 11 h)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
64/cb/a29706746adf35736905084eeaee
Default Alt Text
(16 KB)
Attached To
Mode
R113 roundcubemail
Attached
Detach File
Event Timeline