Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F2513322
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
17 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/program/actions/settings/folders.php b/program/actions/settings/folders.php
index 32a6a77a4..85395eee9 100644
--- a/program/actions/settings/folders.php
+++ b/program/actions/settings/folders.php
@@ -1,378 +1,374 @@
<?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 && !isset($seen[$parent_folder])) {
for ($i = 1; $i <= $level; $i++) {
$ancestor_folder = join($delimiter, array_slice($foldersplit, 0, $i));
if ($ancestor_folder && !$seen[$ancestor_folder]++) {
$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;
}
- if (isset($seen[$folder])) {
- $seen[$folder]++;
- }
- else {
- $seen[$folder] = 1;
- }
+ $seen[$folder] = 1;
$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) && $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 (
- isset($folders[$key+1]['level'])
- && (!isset($data['level']) || $folders[$key+1]['level'] > $data['level'])
- ) {
+ 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 (!rcube_utils::get_boolean($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);
}
}
}
diff --git a/tests/Rcmail/Oauth.php b/tests/Rcmail/Oauth.php
index 2c8e60768..59e0fd449 100644
--- a/tests/Rcmail/Oauth.php
+++ b/tests/Rcmail/Oauth.php
@@ -1,23 +1,30 @@
<?php
/**
* Test class to test rcmail_oauth class
*
* @package Tests
*/
class Rcmail_RcmailOauth extends ActionTestCase
{
/**
* Test jwt_decode() method
*/
function test_jwt_decode()
{
$jwt = 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.EkN-DOsnsuRjRO6BxXemmJDm3HbxrbRzXglbN2S4sOkopdU4IsDxTI8jO19W_A4K8ZPJijNLis4EZsHeY559a4DFOd50_OqgHGuERTqYZyuhtF39yxJPAjUESwxk2J5k_4zM3O-vtd1Ghyo4IbqKKSy6J9mTniYJPenn5-HIirE';
$oauth = rcmail_oauth::get_instance();
- $this->expectException(RuntimeException::class);
+ // We can't use expectException until we drop support for phpunit 4.8 (i.e. PHP 5.4)
+ // $this->expectException(RuntimeException::class);
- $result = $oauth->jwt_decode($jwt);
+ try {
+ $oauth->jwt_decode($jwt);
+ }
+ catch (RuntimeException $e) {
+ }
+
+ $this->assertTrue(isset($e));
}
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sun, Apr 19, 9:38 AM (1 d, 11 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
435843
Default Alt Text
(17 KB)
Attached To
Mode
R3 roundcubemail
Attached
Detach File
Event Timeline
Log In to Comment