Move folder create/rename logic to libkolab for common use in different Kolab plugins
This commit is contained in:
parent
078b953953
commit
dce4ed076b
3 changed files with 105 additions and 103 deletions
|
@ -26,9 +26,6 @@
|
||||||
|
|
||||||
class kolab_calendar
|
class kolab_calendar
|
||||||
{
|
{
|
||||||
const COLOR_KEY_SHARED = '/shared/vendor/kolab/color';
|
|
||||||
const COLOR_KEY_PRIVATE = '/shared/vendor/kolab/color';
|
|
||||||
|
|
||||||
public $id;
|
public $id;
|
||||||
public $ready = false;
|
public $ready = false;
|
||||||
public $readonly = true;
|
public $readonly = true;
|
||||||
|
@ -146,8 +143,8 @@ class kolab_calendar
|
||||||
public function get_color()
|
public function get_color()
|
||||||
{
|
{
|
||||||
// color is defined in folder METADATA
|
// color is defined in folder METADATA
|
||||||
$metadata = $this->storage->get_metadata(array(self::COLOR_KEY_PRIVATE, self::COLOR_KEY_SHARED));
|
$metadata = $this->storage->get_metadata(array(kolab_storage::COLOR_KEY_PRIVATE, kolab_storage::COLOR_KEY_SHARED));
|
||||||
if (($color = $metadata[self::COLOR_KEY_PRIVATE]) || ($color = $metadata[self::COLOR_KEY_SHARED])) {
|
if (($color = $metadata[kolab_storage::COLOR_KEY_PRIVATE]) || ($color = $metadata[kolab_storage::COLOR_KEY_SHARED])) {
|
||||||
return $color;
|
return $color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -154,16 +154,14 @@ class kolab_driver extends calendar_driver
|
||||||
*/
|
*/
|
||||||
public function create_calendar($prop)
|
public function create_calendar($prop)
|
||||||
{
|
{
|
||||||
$folder = $this->folder_update($prop);
|
$prop['type'] = 'event';
|
||||||
|
$prop['subscribed'] = $prop['active'] ? kolab_storage::SERVERSIDE_SUBSCRIPTION : null;
|
||||||
|
$folder = kolab_storage::folder_update($prop);
|
||||||
|
|
||||||
if ($folder === false) {
|
if ($folder === false) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// subscribe to new calendar by default
|
|
||||||
$storage = kolab_storage::get_folder($folder);
|
|
||||||
$storage->subscribe($prop['active'], kolab_storage::SERVERSIDE_SUBSCRIPTION);
|
|
||||||
|
|
||||||
// create ID
|
// create ID
|
||||||
$id = kolab_storage::folder_id($folder);
|
$id = kolab_storage::folder_id($folder);
|
||||||
|
|
||||||
|
@ -190,8 +188,8 @@ class kolab_driver extends calendar_driver
|
||||||
public function edit_calendar($prop)
|
public function edit_calendar($prop)
|
||||||
{
|
{
|
||||||
if ($prop['id'] && ($cal = $this->calendars[$prop['id']])) {
|
if ($prop['id'] && ($cal = $this->calendars[$prop['id']])) {
|
||||||
$oldfolder = $cal->get_realname();
|
$prop['oldname'] = $cal->get_realname();
|
||||||
$newfolder = $this->folder_update($prop);
|
$newfolder = kolab_storage::folder_update($prop);
|
||||||
|
|
||||||
if ($newfolder === false) {
|
if ($newfolder === false) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -234,97 +232,6 @@ class kolab_driver extends calendar_driver
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Rename or Create a new IMAP folder
|
|
||||||
*
|
|
||||||
* @param array Hash array with calendar properties
|
|
||||||
*
|
|
||||||
* @return mixed New folder name or False on failure
|
|
||||||
*/
|
|
||||||
private function folder_update(&$prop)
|
|
||||||
{
|
|
||||||
$folder = rcube_charset::convert($prop['name'], RCMAIL_CHARSET, 'UTF7-IMAP');
|
|
||||||
$oldfolder = $prop['oldname']; // UTF7
|
|
||||||
$parent = $prop['parent']; // UTF7
|
|
||||||
$storage = $this->rc->get_storage();
|
|
||||||
$delimiter = $storage->get_hierarchy_delimiter();
|
|
||||||
|
|
||||||
if (strlen($oldfolder)) {
|
|
||||||
$options = $storage->folder_info($oldfolder);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty($options) && ($options['norename'] || $options['protected'])) {
|
|
||||||
}
|
|
||||||
// sanity checks (from steps/settings/save_folder.inc)
|
|
||||||
else if (!strlen($folder)) {
|
|
||||||
$this->last_error = 'Invalid folder name';
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if (strlen($folder) > 128) {
|
|
||||||
$this->last_error = 'Folder name too long';
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// these characters are problematic e.g. when used in LIST/LSUB
|
|
||||||
foreach (array($delimiter, '%', '*') as $char) {
|
|
||||||
if (strpos($folder, $delimiter) !== false) {
|
|
||||||
$this->last_error = 'Invalid folder name';
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty($options) && ($options['protected'] || $options['norename'])) {
|
|
||||||
$folder = $oldfolder;
|
|
||||||
}
|
|
||||||
else if (strlen($parent)) {
|
|
||||||
$folder = $parent . $delimiter . $folder;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// add namespace prefix (when needed)
|
|
||||||
$folder = $storage->mod_folder($folder, 'in');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check access rights to the parent folder
|
|
||||||
if (strlen($parent) && (!strlen($oldfolder) || $oldfolder != $folder)) {
|
|
||||||
$parent_opts = $storage->folder_info($parent);
|
|
||||||
if ($parent_opts['namespace'] != 'personal'
|
|
||||||
&& (empty($parent_opts['rights']) || !preg_match('/[ck]/', implode($parent_opts['rights'])))
|
|
||||||
) {
|
|
||||||
$this->last_error = 'No permission to create folder';
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// update the folder name
|
|
||||||
if (strlen($oldfolder)) {
|
|
||||||
if ($oldfolder != $folder) {
|
|
||||||
if (!($result = kolab_storage::folder_rename($oldfolder, $folder)))
|
|
||||||
$this->last_error = kolab_storage::$last_error;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
$result = true;
|
|
||||||
}
|
|
||||||
// create new folder
|
|
||||||
else {
|
|
||||||
if (!($result = kolab_storage::folder_create($folder, 'event')))
|
|
||||||
$this->last_error = kolab_storage::$last_error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// save color in METADATA
|
|
||||||
// TODO: also save 'showalarams' and other properties here
|
|
||||||
|
|
||||||
if ($result && $prop['color']) {
|
|
||||||
if (!($meta_saved = $storage->set_metadata(array(kolab_calendar::COLOR_KEY_SHARED => $prop['color'])))) // try in shared namespace
|
|
||||||
$meta_saved = $storage->set_metadata(array(kolab_calendar::COLOR_KEY_PRIVATE => $prop['color'])); // try in private namespace
|
|
||||||
if ($meta_saved)
|
|
||||||
unset($prop['color']); // unsetting will prevent fallback to local user prefs
|
|
||||||
}
|
|
||||||
|
|
||||||
return $result ? $folder : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete the given calendar with all its contents
|
* Delete the given calendar with all its contents
|
||||||
*
|
*
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
class kolab_storage
|
class kolab_storage
|
||||||
{
|
{
|
||||||
const CTYPE_KEY = '/shared/vendor/kolab/folder-type';
|
const CTYPE_KEY = '/shared/vendor/kolab/folder-type';
|
||||||
|
const COLOR_KEY_SHARED = '/shared/vendor/kolab/color';
|
||||||
|
const COLOR_KEY_PRIVATE = '/shared/vendor/kolab/color';
|
||||||
const SERVERSIDE_SUBSCRIPTION = 0;
|
const SERVERSIDE_SUBSCRIPTION = 0;
|
||||||
const CLIENTSIDE_SUBSCRIPTION = 1;
|
const CLIENTSIDE_SUBSCRIPTION = 1;
|
||||||
|
|
||||||
|
@ -222,6 +224,102 @@ class kolab_storage
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rename or Create a new IMAP folder.
|
||||||
|
*
|
||||||
|
* Does additional checks for permissions and folder name restrictions
|
||||||
|
*
|
||||||
|
* @param array Hash array with folder properties and metadata
|
||||||
|
* - name: Folder name
|
||||||
|
* - oldname: Old folder name when changed
|
||||||
|
* - parent: Parent folder to create the new one in
|
||||||
|
* - type: Folder type to create
|
||||||
|
* @return mixed New folder name or False on failure
|
||||||
|
*/
|
||||||
|
public static function folder_update(&$prop)
|
||||||
|
{
|
||||||
|
self::setup();
|
||||||
|
|
||||||
|
$folder = rcube_charset::convert($prop['name'], RCMAIL_CHARSET, 'UTF7-IMAP');
|
||||||
|
$oldfolder = $prop['oldname']; // UTF7
|
||||||
|
$parent = $prop['parent']; // UTF7
|
||||||
|
$delimiter = self::$imap->get_hierarchy_delimiter();
|
||||||
|
|
||||||
|
if (strlen($oldfolder)) {
|
||||||
|
$options = self::$imap->folder_info($oldfolder);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($options) && ($options['norename'] || $options['protected'])) {
|
||||||
|
}
|
||||||
|
// sanity checks (from steps/settings/save_folder.inc)
|
||||||
|
else if (!strlen($folder)) {
|
||||||
|
self::$last_error = 'Invalid folder name';
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (strlen($folder) > 128) {
|
||||||
|
self::$last_error = 'Folder name too long';
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// these characters are problematic e.g. when used in LIST/LSUB
|
||||||
|
foreach (array($delimiter, '%', '*') as $char) {
|
||||||
|
if (strpos($folder, $delimiter) !== false) {
|
||||||
|
self::$last_error = 'Invalid folder name';
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($options) && ($options['protected'] || $options['norename'])) {
|
||||||
|
$folder = $oldfolder;
|
||||||
|
}
|
||||||
|
else if (strlen($parent)) {
|
||||||
|
$folder = $parent . $delimiter . $folder;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// add namespace prefix (when needed)
|
||||||
|
$folder = self::$imap->mod_folder($folder, 'in');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check access rights to the parent folder
|
||||||
|
if (strlen($parent) && (!strlen($oldfolder) || $oldfolder != $folder)) {
|
||||||
|
$parent_opts = self::$imap->folder_info($parent);
|
||||||
|
if ($parent_opts['namespace'] != 'personal'
|
||||||
|
&& (empty($parent_opts['rights']) || !preg_match('/[ck]/', implode($parent_opts['rights'])))
|
||||||
|
) {
|
||||||
|
self::$last_error = 'No permission to create folder';
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// update the folder name
|
||||||
|
if (strlen($oldfolder)) {
|
||||||
|
if ($oldfolder != $folder) {
|
||||||
|
$result = self::folder_rename($oldfolder, $folder);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
$result = true;
|
||||||
|
}
|
||||||
|
// create new folder
|
||||||
|
else {
|
||||||
|
$result = self::folder_create($folder, $prop['type'], $prop['subscribed'] === self::SERVERSIDE_SUBSCRIPTION);
|
||||||
|
}
|
||||||
|
|
||||||
|
// save color in METADATA
|
||||||
|
// TODO: also save 'showalarams' and other properties here
|
||||||
|
// TODO: change private/shared precedence depending on private or shared folder
|
||||||
|
|
||||||
|
if ($result && $prop['color']) {
|
||||||
|
if (!($meta_saved = self::$imap->set_metadata($folder, array(self::COLOR_KEY_SHARED => $prop['color'])))) // try in shared namespace
|
||||||
|
$meta_saved = self::$imap->set_metadata($folder, array(self::COLOR_KEY_PRIVATE => $prop['color'])); // try in private namespace
|
||||||
|
if ($meta_saved)
|
||||||
|
unset($prop['color']); // unsetting will prevent fallback to local user prefs
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result ? $folder : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Getter for human-readable name of Kolab object (folder)
|
* Getter for human-readable name of Kolab object (folder)
|
||||||
* See http://wiki.kolab.org/UI-Concepts/Folder-Listing for reference
|
* See http://wiki.kolab.org/UI-Concepts/Folder-Listing for reference
|
||||||
|
|
Loading…
Add table
Reference in a new issue