Use consistent PHP code style
This commit is contained in:
parent
f3319891d5
commit
5271b6e787
339 changed files with 8405 additions and 8522 deletions
43
.php-cs-fixer.php
Normal file
43
.php-cs-fixer.php
Normal file
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use PhpCsFixer\Config;
|
||||
use PhpCsFixer\Finder;
|
||||
|
||||
$finder = Finder::create()
|
||||
->in([__DIR__ . '/plugins'])
|
||||
->ignoreDotFiles(false)
|
||||
->name('*.inc')
|
||||
->name('*.php.dist');
|
||||
|
||||
return (new Config())
|
||||
->setRiskyAllowed(true)
|
||||
->setRules([
|
||||
'@PHP74Migration' => true,
|
||||
'@PHP74Migration:risky' => true,
|
||||
'@PHP80Migration' => true,
|
||||
'@PSR1' => true,
|
||||
'@PSR12' => true,
|
||||
|
||||
'concat_space' => [
|
||||
'spacing' => 'one',
|
||||
],
|
||||
|
||||
'declare_strict_types' => false,
|
||||
'phpdoc_add_missing_param_annotation' => false,
|
||||
'use_arrow_functions' => false,
|
||||
'void_return' => false,
|
||||
|
||||
'yoda_style' => [
|
||||
'equal' => false,
|
||||
'identical' => false,
|
||||
],
|
||||
|
||||
// TODO - risky
|
||||
'no_unset_on_property' => false,
|
||||
'random_api_migration' => false,
|
||||
'strict_param' => false,
|
||||
])
|
||||
->setFinder($finder)
|
||||
->setCacheFile(sys_get_temp_dir() . '/php-cs-fixer.' . md5(__DIR__) . '.cache');
|
File diff suppressed because it is too large
Load diff
|
@ -81,12 +81,12 @@ $config['calendar_default_alarm_offset'] = '-15M';
|
|||
$config['calendar_event_coloring'] = 0;
|
||||
|
||||
// event categories
|
||||
$config['calendar_categories'] = array(
|
||||
$config['calendar_categories'] = [
|
||||
'Personal' => 'c0c0c0',
|
||||
'Work' => 'ff0000',
|
||||
'Family' => '00ff00',
|
||||
'Holiday' => 'ff6600',
|
||||
);
|
||||
];
|
||||
|
||||
// enable users to invite/edit attendees for shared events organized by others
|
||||
$config['calendar_allow_invite_shared'] = false;
|
||||
|
|
|
@ -59,8 +59,7 @@ class caldav_calendar extends kolab_storage_dav_folder
|
|||
{
|
||||
if ($folder_or_id instanceof kolab_storage_dav_folder) {
|
||||
$this->storage = $folder_or_id;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// $this->storage = kolab_storage_dav::get_folder($folder_or_id, 'event');
|
||||
}
|
||||
|
||||
|
@ -78,13 +77,13 @@ class caldav_calendar extends kolab_storage_dav_folder
|
|||
if ($this->storage->get_namespace() == 'personal') {
|
||||
$this->editable = true;
|
||||
$this->rights = 'lrswikxteav';
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$rights = $this->storage->get_myrights();
|
||||
if ($rights) {
|
||||
$this->rights = $rights;
|
||||
if (strpos($rights, 't') !== false || strpos($rights, 'd') !== false) {
|
||||
$this->editable = strpos($rights, 'i');;
|
||||
$this->editable = strpos($rights, 'i');
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -118,16 +117,16 @@ class caldav_calendar extends kolab_storage_dav_folder
|
|||
*/
|
||||
public function get_caldav_url()
|
||||
{
|
||||
/*
|
||||
if ($template = $this->cal->rc->config->get('calendar_caldav_url', null)) {
|
||||
return strtr($template, [
|
||||
'%h' => $_SERVER['HTTP_HOST'],
|
||||
'%u' => urlencode($this->cal->rc->get_user_name()),
|
||||
'%i' => urlencode($this->storage->get_uid()),
|
||||
'%n' => urlencode($this->name),
|
||||
]);
|
||||
}
|
||||
*/
|
||||
/*
|
||||
if ($template = $this->cal->rc->config->get('calendar_caldav_url', null)) {
|
||||
return strtr($template, [
|
||||
'%h' => $_SERVER['HTTP_HOST'],
|
||||
'%u' => urlencode($this->cal->rc->get_user_name()),
|
||||
'%i' => urlencode($this->storage->get_uid()),
|
||||
'%n' => urlencode($this->name),
|
||||
]);
|
||||
}
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -166,8 +165,7 @@ class caldav_calendar extends kolab_storage_dav_folder
|
|||
// check for match on the first instance already
|
||||
if (!empty($master['_instance']) && $master['_instance'] == $instance_id) {
|
||||
$this->events[$id] = $master;
|
||||
}
|
||||
else if (!empty($master['recurrence'])) {
|
||||
} elseif (!empty($master['recurrence'])) {
|
||||
$start_date = $master['start'];
|
||||
// For performance reasons we'll get only the specific instance
|
||||
if (($date = substr($id, strlen($master_id) + 1, 8)) && strlen($date) == 8 && is_numeric($date)) {
|
||||
|
@ -190,15 +188,15 @@ class caldav_calendar extends kolab_storage_dav_folder
|
|||
{
|
||||
$event = $this->get_event($event['id']);
|
||||
$data = $this->storage->get_attachment($id, $event);
|
||||
/*
|
||||
if ($data === false) {
|
||||
// try again with master UID
|
||||
$uid = preg_replace('/-\d+(T\d{6})?$/', '', $event['id']);
|
||||
if ($uid != $event['id']) {
|
||||
$data = $this->storage->get_attachment($uid, $id); // TODO
|
||||
}
|
||||
}
|
||||
*/
|
||||
/*
|
||||
if ($data === false) {
|
||||
// try again with master UID
|
||||
$uid = preg_replace('/-\d+(T\d{6})?$/', '', $event['id']);
|
||||
if ($uid != $event['id']) {
|
||||
$data = $this->storage->get_attachment($uid, $id); // TODO
|
||||
}
|
||||
}
|
||||
*/
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
@ -219,14 +217,12 @@ class caldav_calendar extends kolab_storage_dav_folder
|
|||
// to workaround possible timezone differences
|
||||
try {
|
||||
$start = new DateTime('@' . ($start - 12 * 3600));
|
||||
}
|
||||
catch (Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
$start = new DateTime('@0');
|
||||
}
|
||||
try {
|
||||
$end = new DateTime('@' . ($end + 12 * 3600));
|
||||
}
|
||||
catch (Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
$end = new DateTime('today +10 years');
|
||||
}
|
||||
|
||||
|
@ -323,7 +319,7 @@ class caldav_calendar extends kolab_storage_dav_folder
|
|||
$events = array_merge($events, $this->get_recurring_events($event, $start, $end));
|
||||
}
|
||||
// add top-level exceptions (aka loose single occurrences)
|
||||
else if (!empty($record['exceptions'])) {
|
||||
elseif (!empty($record['exceptions'])) {
|
||||
foreach ($record['exceptions'] as $ex) {
|
||||
$component = $this->_to_driver_event($ex, false, false, $record);
|
||||
if ($component['start'] <= $end && $component['end'] >= $start) {
|
||||
|
@ -335,7 +331,7 @@ class caldav_calendar extends kolab_storage_dav_folder
|
|||
|
||||
// post-filter all events by fulltext search and partstat values
|
||||
$me = $this;
|
||||
$events = array_filter($events, function($event) use ($words, $partstat_exclude, $user_emails, $me) {
|
||||
$events = array_filter($events, function ($event) use ($words, $partstat_exclude, $user_emails, $me) {
|
||||
// fulltext search
|
||||
if (count($words)) {
|
||||
$hits = 0;
|
||||
|
@ -382,16 +378,14 @@ class caldav_calendar extends kolab_storage_dav_folder
|
|||
{
|
||||
// convert to DateTime for comparisons
|
||||
try {
|
||||
$start = new DateTime('@'.$start);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
$start = new DateTime('@' . $start);
|
||||
} catch (Exception $e) {
|
||||
$start = new DateTime('@0');
|
||||
}
|
||||
if ($end) {
|
||||
try {
|
||||
$end = new DateTime('@'.$end);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
$end = new DateTime('@' . $end);
|
||||
} catch (Exception $e) {
|
||||
$end = null;
|
||||
}
|
||||
}
|
||||
|
@ -409,8 +403,7 @@ class caldav_calendar extends kolab_storage_dav_folder
|
|||
$query[] = ['tags', '!=', 'x-partstat:' . $email . ':needs-action'];
|
||||
$query[] = ['tags', '!=', 'x-partstat:' . $email . ':declined'];
|
||||
}
|
||||
}
|
||||
else if (is_array($filter_query)) {
|
||||
} elseif (is_array($filter_query)) {
|
||||
$query = array_merge($query, $filter_query);
|
||||
}
|
||||
|
||||
|
@ -439,11 +432,13 @@ class caldav_calendar extends kolab_storage_dav_folder
|
|||
$saved = $this->storage->save($object, 'event');
|
||||
|
||||
if (!$saved) {
|
||||
rcube::raise_error([
|
||||
rcube::raise_error(
|
||||
[
|
||||
'code' => 600, 'file' => __FILE__, 'line' => __LINE__,
|
||||
'message' => "Error saving event object to DAV server"
|
||||
'message' => "Error saving event object to DAV server",
|
||||
],
|
||||
true, false
|
||||
true,
|
||||
false
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
@ -483,14 +478,15 @@ class caldav_calendar extends kolab_storage_dav_folder
|
|||
$saved = $this->storage->save($object, 'event', $old['uid']);
|
||||
|
||||
if (!$saved) {
|
||||
rcube::raise_error([
|
||||
rcube::raise_error(
|
||||
[
|
||||
'code' => 600, 'file' => __FILE__, 'line' => __LINE__,
|
||||
'message' => "Error saving event object to CalDAV server"
|
||||
'message' => "Error saving event object to CalDAV server",
|
||||
],
|
||||
true, false
|
||||
true,
|
||||
false
|
||||
);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// save links in configuration.relation object
|
||||
// if ($this->save_links($event['uid'], $links)) {
|
||||
// $object['links'] = $links;
|
||||
|
@ -521,11 +517,13 @@ class caldav_calendar extends kolab_storage_dav_folder
|
|||
$deleted = $this->storage->delete($uid, $force);
|
||||
|
||||
if (!$deleted) {
|
||||
rcube::raise_error([
|
||||
rcube::raise_error(
|
||||
[
|
||||
'code' => 600, 'file' => __FILE__, 'line' => __LINE__,
|
||||
'message' => "Error deleting event '{$uid}' from CalDAV server"
|
||||
'message' => "Error deleting event '{$uid}' from CalDAV server",
|
||||
],
|
||||
true, false
|
||||
true,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -697,8 +695,7 @@ class caldav_calendar extends kolab_storage_dav_folder
|
|||
if ($limit && count($events) >= $limit) {
|
||||
return $events;
|
||||
}
|
||||
}
|
||||
else if ($next_event['start'] > $end) {
|
||||
} elseif ($next_event['start'] > $end) {
|
||||
// stop loop if out of range
|
||||
break;
|
||||
}
|
||||
|
@ -746,14 +743,13 @@ class caldav_calendar extends kolab_storage_dav_folder
|
|||
&& empty($record['recurrence_id']) && empty($record['_instance'])
|
||||
) {
|
||||
$record['_instance'] = $record['start']->format($recurrence_id_format);
|
||||
}
|
||||
else if (isset($record['recurrence_date']) && $record['recurrence_date'] instanceof DateTimeInterface) {
|
||||
} elseif (isset($record['recurrence_date']) && $record['recurrence_date'] instanceof DateTimeInterface) {
|
||||
$record['_instance'] = $record['recurrence_date']->format($recurrence_id_format);
|
||||
}
|
||||
|
||||
// clean up exception data
|
||||
if (!empty($record['recurrence']) && !empty($record['recurrence']['EXCEPTIONS'])) {
|
||||
array_walk($record['recurrence']['EXCEPTIONS'], function(&$exception) {
|
||||
array_walk($record['recurrence']['EXCEPTIONS'], function (&$exception) {
|
||||
unset($exception['_attachments']);
|
||||
});
|
||||
}
|
||||
|
@ -804,7 +800,7 @@ class caldav_calendar extends kolab_storage_dav_folder
|
|||
}
|
||||
|
||||
// remove some internal properties which should not be cached
|
||||
$cleanup_fn = function(&$event) {
|
||||
$cleanup_fn = function (&$event) {
|
||||
unset($event['_savemode'], $event['_fromcalendar'], $event['_identity'], $event['_folder_id'],
|
||||
$event['calendar'], $event['className'], $event['recurrence_id'],
|
||||
$event['attachments'], $event['deleted_attachments']);
|
||||
|
@ -866,13 +862,11 @@ class caldav_calendar extends kolab_storage_dav_folder
|
|||
foreach ($prop as $key => $val) {
|
||||
if (is_numeric($key)) {
|
||||
$out .= self::_complex2string($val);
|
||||
}
|
||||
else if (!in_array($key, $ignorekeys)) {
|
||||
} elseif (!in_array($key, $ignorekeys)) {
|
||||
$out .= $val . ' ';
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (is_string($prop) || is_numeric($prop)) {
|
||||
} elseif (is_string($prop) || is_numeric($prop)) {
|
||||
$out .= $prop . ' ';
|
||||
}
|
||||
|
||||
|
|
|
@ -80,7 +80,7 @@ class caldav_driver extends kolab_driver
|
|||
|
||||
// get all folders that support VEVENT, sorted by namespace/name
|
||||
$folders = $this->storage->get_folders('event');
|
||||
// + $this->storage->get_user_folders('event', true);
|
||||
// + $this->storage->get_user_folders('event', true);
|
||||
|
||||
$this->calendars = [];
|
||||
|
||||
|
@ -109,8 +109,7 @@ class caldav_driver extends kolab_driver
|
|||
if ($folder instanceof kolab_storage_folder_user) {
|
||||
$calendar = new kolab_user_calendar($folder, $this->cal);
|
||||
$calendar->subscriptions = count($folder->children) > 0;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$calendar = new caldav_calendar($folder, $this->cal);
|
||||
}
|
||||
|
||||
|
@ -134,121 +133,121 @@ class caldav_driver extends kolab_driver
|
|||
$prefs = $this->rc->config->get('kolab_calendars', []);
|
||||
|
||||
// include virtual folders for a full folder tree
|
||||
/*
|
||||
if (!is_null($tree)) {
|
||||
$folders = $this->storage->folder_hierarchy($folders, $tree);
|
||||
}
|
||||
*/
|
||||
/*
|
||||
if (!is_null($tree)) {
|
||||
$folders = $this->storage->folder_hierarchy($folders, $tree);
|
||||
}
|
||||
*/
|
||||
$parents = array_keys($this->calendars);
|
||||
|
||||
foreach ($folders as $id => $cal) {
|
||||
$parent_id = null;
|
||||
/*
|
||||
$path = explode('/', $cal->name);
|
||||
/*
|
||||
$path = explode('/', $cal->name);
|
||||
|
||||
// find parent
|
||||
do {
|
||||
array_pop($path);
|
||||
$parent_id = $this->storage->folder_id(implode('/', $path));
|
||||
}
|
||||
while (count($path) > 1 && !in_array($parent_id, $parents));
|
||||
// find parent
|
||||
do {
|
||||
array_pop($path);
|
||||
$parent_id = $this->storage->folder_id(implode('/', $path));
|
||||
}
|
||||
while (count($path) > 1 && !in_array($parent_id, $parents));
|
||||
|
||||
// restore "real" parent ID
|
||||
if ($parent_id && !in_array($parent_id, $parents)) {
|
||||
$parent_id = $this->storage->folder_id($cal->get_parent());
|
||||
}
|
||||
// restore "real" parent ID
|
||||
if ($parent_id && !in_array($parent_id, $parents)) {
|
||||
$parent_id = $this->storage->folder_id($cal->get_parent());
|
||||
}
|
||||
|
||||
$parents[] = $cal->id;
|
||||
$parents[] = $cal->id;
|
||||
|
||||
if ($cal instanceof kolab_storage_folder_virtual) {
|
||||
$calendars[$cal->id] = [
|
||||
'id' => $cal->id,
|
||||
'name' => $cal->get_name(),
|
||||
'listname' => $cal->get_foldername(),
|
||||
'editname' => $cal->get_foldername(),
|
||||
'virtual' => true,
|
||||
'editable' => false,
|
||||
'group' => $cal->get_namespace(),
|
||||
if ($cal instanceof kolab_storage_folder_virtual) {
|
||||
$calendars[$cal->id] = [
|
||||
'id' => $cal->id,
|
||||
'name' => $cal->get_name(),
|
||||
'listname' => $cal->get_foldername(),
|
||||
'editname' => $cal->get_foldername(),
|
||||
'virtual' => true,
|
||||
'editable' => false,
|
||||
'group' => $cal->get_namespace(),
|
||||
];
|
||||
}
|
||||
else {
|
||||
*/
|
||||
// additional folders may come from kolab_storage_dav::folder_hierarchy() above
|
||||
// make sure we deal with caldav_calendar instances
|
||||
$cal = $this->_to_calendar($cal);
|
||||
$this->calendars[$cal->id] = $cal;
|
||||
|
||||
$is_user = false; // ($cal instanceof caldav_user_calendar);
|
||||
|
||||
$calendars[$cal->id] = [
|
||||
'id' => $cal->id,
|
||||
'name' => $cal->get_name(),
|
||||
'listname' => $cal->get_foldername(),
|
||||
'editname' => $cal->get_foldername(),
|
||||
'title' => '', // $cal->get_title(),
|
||||
'color' => $cal->get_color(),
|
||||
'editable' => $cal->editable,
|
||||
'group' => $is_user ? 'other user' : $cal->get_namespace(),
|
||||
'active' => !isset($prefs[$cal->id]['active']) || !empty($prefs[$cal->id]['active']),
|
||||
'owner' => $cal->get_owner(),
|
||||
'removable' => !$cal->default,
|
||||
// extras to hide some elements in the UI
|
||||
'subscriptions' => $cal->subscriptions,
|
||||
'driver' => 'caldav',
|
||||
];
|
||||
|
||||
if (!$is_user) {
|
||||
$calendars[$cal->id] += [
|
||||
'default' => $cal->default,
|
||||
'rights' => $cal->rights,
|
||||
'showalarms' => $cal->alarms,
|
||||
'history' => !empty($this->bonnie_api),
|
||||
'children' => true, // TODO: determine if that folder indeed has child folders
|
||||
'parent' => $parent_id,
|
||||
'subtype' => $cal->subtype,
|
||||
'caldavurl' => '', // $cal->get_caldav_url(),
|
||||
];
|
||||
}
|
||||
else {
|
||||
*/
|
||||
// additional folders may come from kolab_storage_dav::folder_hierarchy() above
|
||||
// make sure we deal with caldav_calendar instances
|
||||
$cal = $this->_to_calendar($cal);
|
||||
$this->calendars[$cal->id] = $cal;
|
||||
|
||||
$is_user = false; // ($cal instanceof caldav_user_calendar);
|
||||
|
||||
$calendars[$cal->id] = [
|
||||
'id' => $cal->id,
|
||||
'name' => $cal->get_name(),
|
||||
'listname' => $cal->get_foldername(),
|
||||
'editname' => $cal->get_foldername(),
|
||||
'title' => '', // $cal->get_title(),
|
||||
'color' => $cal->get_color(),
|
||||
'editable' => $cal->editable,
|
||||
'group' => $is_user ? 'other user' : $cal->get_namespace(),
|
||||
'active' => !isset($prefs[$cal->id]['active']) || !empty($prefs[$cal->id]['active']),
|
||||
'owner' => $cal->get_owner(),
|
||||
'removable' => !$cal->default,
|
||||
// extras to hide some elements in the UI
|
||||
'subscriptions' => $cal->subscriptions,
|
||||
'driver' => 'caldav',
|
||||
];
|
||||
|
||||
if (!$is_user) {
|
||||
$calendars[$cal->id] += [
|
||||
'default' => $cal->default,
|
||||
'rights' => $cal->rights,
|
||||
'showalarms' => $cal->alarms,
|
||||
'history' => !empty($this->bonnie_api),
|
||||
'children' => true, // TODO: determine if that folder indeed has child folders
|
||||
'parent' => $parent_id,
|
||||
'subtype' => $cal->subtype,
|
||||
'caldavurl' => '', // $cal->get_caldav_url(),
|
||||
];
|
||||
}
|
||||
/*
|
||||
}
|
||||
*/
|
||||
/*
|
||||
}
|
||||
*/
|
||||
if ($cal->subscriptions) {
|
||||
$calendars[$cal->id]['subscribed'] = $cal->is_subscribed();
|
||||
}
|
||||
}
|
||||
/*
|
||||
// list virtual calendars showing invitations
|
||||
if ($this->rc->config->get('kolab_invitation_calendars') && !($filter & self::FILTER_INSERTABLE)) {
|
||||
foreach ([self::INVITATIONS_CALENDAR_PENDING, self::INVITATIONS_CALENDAR_DECLINED] as $id) {
|
||||
$cal = new caldav_invitation_calendar($id, $this->cal);
|
||||
if (!($filter & self::FILTER_ACTIVE) || $cal->is_active()) {
|
||||
$calendars[$id] = [
|
||||
'id' => $cal->id,
|
||||
'name' => $cal->get_name(),
|
||||
'listname' => $cal->get_name(),
|
||||
'editname' => $cal->get_foldername(),
|
||||
'title' => $cal->get_title(),
|
||||
'color' => $cal->get_color(),
|
||||
'editable' => $cal->editable,
|
||||
'rights' => $cal->rights,
|
||||
'showalarms' => $cal->alarms,
|
||||
'history' => !empty($this->bonnie_api),
|
||||
'group' => 'x-invitations',
|
||||
'default' => false,
|
||||
'active' => $cal->is_active(),
|
||||
'owner' => $cal->get_owner(),
|
||||
'children' => false,
|
||||
'counts' => $id == self::INVITATIONS_CALENDAR_PENDING,
|
||||
];
|
||||
/*
|
||||
// list virtual calendars showing invitations
|
||||
if ($this->rc->config->get('kolab_invitation_calendars') && !($filter & self::FILTER_INSERTABLE)) {
|
||||
foreach ([self::INVITATIONS_CALENDAR_PENDING, self::INVITATIONS_CALENDAR_DECLINED] as $id) {
|
||||
$cal = new caldav_invitation_calendar($id, $this->cal);
|
||||
if (!($filter & self::FILTER_ACTIVE) || $cal->is_active()) {
|
||||
$calendars[$id] = [
|
||||
'id' => $cal->id,
|
||||
'name' => $cal->get_name(),
|
||||
'listname' => $cal->get_name(),
|
||||
'editname' => $cal->get_foldername(),
|
||||
'title' => $cal->get_title(),
|
||||
'color' => $cal->get_color(),
|
||||
'editable' => $cal->editable,
|
||||
'rights' => $cal->rights,
|
||||
'showalarms' => $cal->alarms,
|
||||
'history' => !empty($this->bonnie_api),
|
||||
'group' => 'x-invitations',
|
||||
'default' => false,
|
||||
'active' => $cal->is_active(),
|
||||
'owner' => $cal->get_owner(),
|
||||
'children' => false,
|
||||
'counts' => $id == self::INVITATIONS_CALENDAR_PENDING,
|
||||
];
|
||||
|
||||
|
||||
if (is_object($tree)) {
|
||||
$tree->children[] = $cal;
|
||||
if (is_object($tree)) {
|
||||
$tree->children[] = $cal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
*/
|
||||
// append the virtual birthdays calendar
|
||||
if ($this->rc->config->get('calendar_contact_birthdays', false) && !($filter & self::FILTER_INSERTABLE)) {
|
||||
$id = self::BIRTHDAY_CALENDAR_ID;
|
||||
|
@ -353,8 +352,7 @@ class caldav_driver extends kolab_driver
|
|||
|
||||
if (isset($prop['showalarms']) && $id == self::BIRTHDAY_CALENDAR_ID) {
|
||||
$prefs['calendar_birthdays_alarm_type'] = $prop['showalarms'] ? $this->alarm_types[0] : '';
|
||||
}
|
||||
else if (isset($prop['showalarms'])) {
|
||||
} elseif (isset($prop['showalarms'])) {
|
||||
$prefs['kolab_calendars'][$id]['showalarms'] = !empty($prop['showalarms']);
|
||||
}
|
||||
|
||||
|
@ -422,40 +420,40 @@ class caldav_driver extends kolab_driver
|
|||
{
|
||||
$this->calendars = [];
|
||||
$this->search_more_results = false;
|
||||
/*
|
||||
// find unsubscribed IMAP folders that have "event" type
|
||||
if ($source == 'folders') {
|
||||
foreach ((array) $this->storage->search_folders('event', $query, ['other']) as $folder) {
|
||||
$calendar = new kolab_calendar($folder->name, $this->cal);
|
||||
$this->calendars[$calendar->id] = $calendar;
|
||||
}
|
||||
}
|
||||
// find other user's virtual calendars
|
||||
else if ($source == 'users') {
|
||||
// we have slightly more space, so display twice the number
|
||||
$limit = $this->rc->config->get('autocomplete_max', 15) * 2;
|
||||
|
||||
foreach ($this->storage->search_users($query, 0, [], $limit, $count) as $user) {
|
||||
$calendar = new caldav_user_calendar($user, $this->cal);
|
||||
$this->calendars[$calendar->id] = $calendar;
|
||||
|
||||
// search for calendar folders shared by this user
|
||||
foreach ($this->storage->list_user_folders($user, 'event', false) as $foldername) {
|
||||
$cal = new caldav_calendar($foldername, $this->cal);
|
||||
$this->calendars[$cal->id] = $cal;
|
||||
$calendar->subscriptions = true;
|
||||
/*
|
||||
// find unsubscribed IMAP folders that have "event" type
|
||||
if ($source == 'folders') {
|
||||
foreach ((array) $this->storage->search_folders('event', $query, ['other']) as $folder) {
|
||||
$calendar = new kolab_calendar($folder->name, $this->cal);
|
||||
$this->calendars[$calendar->id] = $calendar;
|
||||
}
|
||||
}
|
||||
}
|
||||
// find other user's virtual calendars
|
||||
else if ($source == 'users') {
|
||||
// we have slightly more space, so display twice the number
|
||||
$limit = $this->rc->config->get('autocomplete_max', 15) * 2;
|
||||
|
||||
if ($count > $limit) {
|
||||
$this->search_more_results = true;
|
||||
}
|
||||
}
|
||||
foreach ($this->storage->search_users($query, 0, [], $limit, $count) as $user) {
|
||||
$calendar = new caldav_user_calendar($user, $this->cal);
|
||||
$this->calendars[$calendar->id] = $calendar;
|
||||
|
||||
// don't list the birthday calendar
|
||||
$this->rc->config->set('calendar_contact_birthdays', false);
|
||||
$this->rc->config->set('kolab_invitation_calendars', false);
|
||||
*/
|
||||
// search for calendar folders shared by this user
|
||||
foreach ($this->storage->list_user_folders($user, 'event', false) as $foldername) {
|
||||
$cal = new caldav_calendar($foldername, $this->cal);
|
||||
$this->calendars[$cal->id] = $cal;
|
||||
$calendar->subscriptions = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($count > $limit) {
|
||||
$this->search_more_results = true;
|
||||
}
|
||||
}
|
||||
|
||||
// don't list the birthday calendar
|
||||
$this->rc->config->set('calendar_contact_birthdays', false);
|
||||
$this->rc->config->set('kolab_invitation_calendars', false);
|
||||
*/
|
||||
return $this->list_calendars();
|
||||
}
|
||||
|
||||
|
@ -475,8 +473,7 @@ class caldav_driver extends kolab_driver
|
|||
{
|
||||
if ($calendars && is_string($calendars)) {
|
||||
$calendars = explode(',', $calendars);
|
||||
}
|
||||
else if (!$calendars) {
|
||||
} elseif (!$calendars) {
|
||||
$this->_read_calendars();
|
||||
$calendars = array_keys($this->calendars);
|
||||
}
|
||||
|
@ -506,7 +503,7 @@ class caldav_driver extends kolab_driver
|
|||
$newcats = array_udiff(
|
||||
array_keys($categories),
|
||||
array_keys($old_categories),
|
||||
function($a, $b) { return strcasecmp($a, $b); }
|
||||
function ($a, $b) { return strcasecmp($a, $b); }
|
||||
);
|
||||
|
||||
if (!empty($newcats)) {
|
||||
|
@ -579,8 +576,7 @@ class caldav_driver extends kolab_driver
|
|||
&& in_array(strtolower($attendee['email']), $emails)
|
||||
) {
|
||||
$is_organizer = true;
|
||||
}
|
||||
else if ($attendee['role'] != 'ORGANIZER'
|
||||
} elseif ($attendee['role'] != 'ORGANIZER'
|
||||
&& $attendee['role'] != 'NON-PARTICIPANT'
|
||||
&& $attendee['status'] != 'DELEGATED'
|
||||
) {
|
||||
|
@ -600,7 +596,7 @@ class caldav_driver extends kolab_driver
|
|||
|
||||
/**
|
||||
* Identify changes considered relevant for scheduling
|
||||
*
|
||||
*
|
||||
* @param array Hash array with NEW object properties
|
||||
* @param array Hash array with OLD object properties
|
||||
*
|
||||
|
@ -631,8 +627,7 @@ class caldav_driver extends kolab_driver
|
|||
// advanced rrule comparison: no rescheduling if series was shortened
|
||||
if ($a['COUNT'] && $b['COUNT'] && $b['COUNT'] < $a['COUNT']) {
|
||||
unset($a['COUNT'], $b['COUNT']);
|
||||
}
|
||||
else if ($a['UNTIL'] && $b['UNTIL'] && $b['UNTIL'] < $a['UNTIL']) {
|
||||
} elseif ($a['UNTIL'] && $b['UNTIL'] && $b['UNTIL'] < $a['UNTIL']) {
|
||||
unset($a['UNTIL'], $b['UNTIL']);
|
||||
}
|
||||
}
|
||||
|
@ -660,7 +655,7 @@ class caldav_driver extends kolab_driver
|
|||
$special_calendars = [
|
||||
self::BIRTHDAY_CALENDAR_ID,
|
||||
self::INVITATIONS_CALENDAR_PENDING,
|
||||
self::INVITATIONS_CALENDAR_DECLINED
|
||||
self::INVITATIONS_CALENDAR_DECLINED,
|
||||
];
|
||||
|
||||
// show default dialog for birthday calendar
|
||||
|
|
|
@ -94,15 +94,15 @@
|
|||
*/
|
||||
abstract class calendar_driver
|
||||
{
|
||||
const FILTER_ALL = 0;
|
||||
const FILTER_WRITEABLE = 1;
|
||||
const FILTER_INSERTABLE = 2;
|
||||
const FILTER_ACTIVE = 4;
|
||||
const FILTER_PERSONAL = 8;
|
||||
const FILTER_PRIVATE = 16;
|
||||
const FILTER_CONFIDENTIAL = 32;
|
||||
const FILTER_SHARED = 64;
|
||||
const BIRTHDAY_CALENDAR_ID = '__bdays__';
|
||||
public const FILTER_ALL = 0;
|
||||
public const FILTER_WRITEABLE = 1;
|
||||
public const FILTER_INSERTABLE = 2;
|
||||
public const FILTER_ACTIVE = 4;
|
||||
public const FILTER_PERSONAL = 8;
|
||||
public const FILTER_PRIVATE = 16;
|
||||
public const FILTER_CONFIDENTIAL = 32;
|
||||
public const FILTER_SHARED = 64;
|
||||
public const BIRTHDAY_CALENDAR_ID = '__bdays__';
|
||||
|
||||
// features supported by backend
|
||||
public $alarms = false;
|
||||
|
@ -131,7 +131,7 @@ abstract class calendar_driver
|
|||
*
|
||||
* @return array List of calendars
|
||||
*/
|
||||
abstract function list_calendars($filter = 0);
|
||||
abstract public function list_calendars($filter = 0);
|
||||
|
||||
/**
|
||||
* Create a new calendar assigned to the current user
|
||||
|
@ -143,7 +143,7 @@ abstract class calendar_driver
|
|||
*
|
||||
* @return mixed ID of the calendar on success, False on error
|
||||
*/
|
||||
abstract function create_calendar($prop);
|
||||
abstract public function create_calendar($prop);
|
||||
|
||||
/**
|
||||
* Update properties of an existing calendar
|
||||
|
@ -156,7 +156,7 @@ abstract class calendar_driver
|
|||
*
|
||||
* @return bool True on success, Fales on failure
|
||||
*/
|
||||
abstract function edit_calendar($prop);
|
||||
abstract public function edit_calendar($prop);
|
||||
|
||||
/**
|
||||
* Set active/subscribed state of a calendar
|
||||
|
@ -167,7 +167,7 @@ abstract class calendar_driver
|
|||
*
|
||||
* @return bool True on success, Fales on failure
|
||||
*/
|
||||
abstract function subscribe_calendar($prop);
|
||||
abstract public function subscribe_calendar($prop);
|
||||
|
||||
/**
|
||||
* Delete the given calendar with all its contents
|
||||
|
@ -177,7 +177,7 @@ abstract class calendar_driver
|
|||
*
|
||||
* @return bool True on success, Fales on failure
|
||||
*/
|
||||
abstract function delete_calendar($prop);
|
||||
abstract public function delete_calendar($prop);
|
||||
|
||||
/**
|
||||
* Search for shared or otherwise not listed calendars the user has access
|
||||
|
@ -187,7 +187,7 @@ abstract class calendar_driver
|
|||
*
|
||||
* @return array List of calendars
|
||||
*/
|
||||
abstract function search_calendars($query, $source);
|
||||
abstract public function search_calendars($query, $source);
|
||||
|
||||
/**
|
||||
* Add a single event to the database
|
||||
|
@ -196,7 +196,7 @@ abstract class calendar_driver
|
|||
*
|
||||
* @return mixed New event ID on success, False on error
|
||||
*/
|
||||
abstract function new_event($event);
|
||||
abstract public function new_event($event);
|
||||
|
||||
/**
|
||||
* Update an event entry with the given data
|
||||
|
@ -205,7 +205,7 @@ abstract class calendar_driver
|
|||
*
|
||||
* @return bool True on success, False on error
|
||||
*/
|
||||
abstract function edit_event($event);
|
||||
abstract public function edit_event($event);
|
||||
|
||||
/**
|
||||
* Extended event editing with possible changes to the argument
|
||||
|
@ -245,7 +245,7 @@ abstract class calendar_driver
|
|||
*
|
||||
* @return bool True on success, False on error
|
||||
*/
|
||||
abstract function move_event($event);
|
||||
abstract public function move_event($event);
|
||||
|
||||
/**
|
||||
* Resize a single event
|
||||
|
@ -257,7 +257,7 @@ abstract class calendar_driver
|
|||
*
|
||||
* @return bool True on success, False on error
|
||||
*/
|
||||
abstract function resize_event($event);
|
||||
abstract public function resize_event($event);
|
||||
|
||||
/**
|
||||
* Remove a single event from the database
|
||||
|
@ -269,7 +269,7 @@ abstract class calendar_driver
|
|||
*
|
||||
* @return bool True on success, False on error
|
||||
*/
|
||||
abstract function remove_event($event, $force = true);
|
||||
abstract public function remove_event($event, $force = true);
|
||||
|
||||
/**
|
||||
* Restores a single deleted event (if supported)
|
||||
|
@ -298,7 +298,7 @@ abstract class calendar_driver
|
|||
*
|
||||
* @return array Event object as hash array
|
||||
*/
|
||||
abstract function get_event($event, $scope = 0, $full = false);
|
||||
abstract public function get_event($event, $scope = 0, $full = false);
|
||||
|
||||
/**
|
||||
* Get events from source.
|
||||
|
@ -312,7 +312,7 @@ abstract class calendar_driver
|
|||
*
|
||||
* @return array A list of event objects (see header of this file for struct of an event)
|
||||
*/
|
||||
abstract function load_events($start, $end, $query = null, $calendars = null, $virtual = 1, $modifiedsince = null);
|
||||
abstract public function load_events($start, $end, $query = null, $calendars = null, $virtual = 1, $modifiedsince = null);
|
||||
|
||||
/**
|
||||
* Get number of events in the given calendar
|
||||
|
@ -323,7 +323,7 @@ abstract class calendar_driver
|
|||
*
|
||||
* @return array Hash array with counts grouped by calendar ID
|
||||
*/
|
||||
abstract function count_events($calendars, $start, $end = null);
|
||||
abstract public function count_events($calendars, $start, $end = null);
|
||||
|
||||
/**
|
||||
* Get a list of pending alarms to be displayed to the user
|
||||
|
@ -340,7 +340,7 @@ abstract class calendar_driver
|
|||
* title: Event title/summary
|
||||
* location: Location string
|
||||
*/
|
||||
abstract function pending_alarms($time, $calendars = null);
|
||||
abstract public function pending_alarms($time, $calendars = null);
|
||||
|
||||
/**
|
||||
* (User) feedback after showing an alarm notification
|
||||
|
@ -349,7 +349,7 @@ abstract class calendar_driver
|
|||
* @param string $event_id Event identifier
|
||||
* @param int $snooze Suspend the alarm for this number of seconds
|
||||
*/
|
||||
abstract function dismiss_alarm($event_id, $snooze = 0);
|
||||
abstract public function dismiss_alarm($event_id, $snooze = 0);
|
||||
|
||||
/**
|
||||
* Check the given event object for validity
|
||||
|
@ -455,17 +455,23 @@ abstract class calendar_driver
|
|||
/**
|
||||
* Create a new category
|
||||
*/
|
||||
public function add_category($name, $color) { }
|
||||
public function add_category($name, $color)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the given category
|
||||
*/
|
||||
public function remove_category($name) { }
|
||||
public function remove_category($name)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Update/replace a category
|
||||
*/
|
||||
public function replace_category($oldname, $name, $color) { }
|
||||
public function replace_category($oldname, $name, $color)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch free/busy information from a person within the given range
|
||||
|
@ -502,9 +508,12 @@ abstract class calendar_driver
|
|||
// determine a reasonable end date if none given
|
||||
if (!$end) {
|
||||
switch ($event['recurrence']['FREQ']) {
|
||||
case 'YEARLY': $intvl = 'P100Y'; break;
|
||||
case 'MONTHLY': $intvl = 'P20Y'; break;
|
||||
default: $intvl = 'P10Y'; break;
|
||||
case 'YEARLY': $intvl = 'P100Y';
|
||||
break;
|
||||
case 'MONTHLY': $intvl = 'P20Y';
|
||||
break;
|
||||
default: $intvl = 'P10Y';
|
||||
break;
|
||||
}
|
||||
|
||||
$end = clone $event['start'];
|
||||
|
@ -519,8 +528,7 @@ abstract class calendar_driver
|
|||
$next_event['id'] = $next_event['uid'] . '-' . $next_event['_instance'];
|
||||
$next_event['recurrence_id'] = $event['uid'];
|
||||
$events[] = $next_event;
|
||||
}
|
||||
else if ($next_event['start'] > $end) { // stop loop if out of range
|
||||
} elseif ($next_event['start'] > $end) { // stop loop if out of range
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -650,8 +658,8 @@ abstract class calendar_driver
|
|||
}
|
||||
|
||||
// convert to DateTime for comparisons
|
||||
$start = new DateTime('@'.$start);
|
||||
$end = new DateTime('@'.$end);
|
||||
$start = new DateTime('@' . $start);
|
||||
$end = new DateTime('@' . $end);
|
||||
// extract the current year
|
||||
$year = $start->format('Y');
|
||||
$year2 = $end->format('Y');
|
||||
|
@ -762,7 +770,7 @@ abstract class calendar_driver
|
|||
public function get_birthday_event($id)
|
||||
{
|
||||
// decode $id
|
||||
list(, $source, $contact_id, $year) = explode(':', rcube_ldap::dn_decode($id));
|
||||
[, $source, $contact_id, $year] = explode(':', rcube_ldap::dn_decode($id));
|
||||
|
||||
$rcmail = rcmail::get_instance();
|
||||
|
||||
|
@ -797,15 +805,16 @@ abstract class calendar_driver
|
|||
|
||||
try {
|
||||
$bday = libcalendaring_datetime::createFromAny($contact['birthday'], true);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
rcube::raise_error([
|
||||
} catch (Exception $e) {
|
||||
rcube::raise_error(
|
||||
[
|
||||
'code' => 600,
|
||||
'file' => __FILE__,
|
||||
'line' => __LINE__,
|
||||
'message' => 'Failed to parse contact birthday: ' . $e->getMessage()
|
||||
'message' => 'Failed to parse contact birthday: ' . $e->getMessage(),
|
||||
],
|
||||
true, false
|
||||
true,
|
||||
false
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -26,24 +26,24 @@
|
|||
|
||||
class database_driver extends calendar_driver
|
||||
{
|
||||
const DB_DATE_FORMAT = 'Y-m-d H:i:s';
|
||||
public const DB_DATE_FORMAT = 'Y-m-d H:i:s';
|
||||
|
||||
public static $scheduling_properties = array('start', 'end', 'allday', 'recurrence', 'location', 'cancelled');
|
||||
public static $scheduling_properties = ['start', 'end', 'allday', 'recurrence', 'location', 'cancelled'];
|
||||
|
||||
// features this backend supports
|
||||
public $alarms = true;
|
||||
public $attendees = true;
|
||||
public $freebusy = false;
|
||||
public $attachments = true;
|
||||
public $alarm_types = array('DISPLAY');
|
||||
public $alarm_types = ['DISPLAY'];
|
||||
|
||||
private $rc;
|
||||
private $cal;
|
||||
private $cache = array();
|
||||
private $calendars = array();
|
||||
private $cache = [];
|
||||
private $calendars = [];
|
||||
private $calendar_ids = '';
|
||||
private $free_busy_map = array('free' => 0, 'busy' => 1, 'out-of-office' => 2, 'outofoffice' => 2, 'tentative' => 3);
|
||||
private $sensitivity_map = array('public' => 0, 'private' => 1, 'confidential' => 2);
|
||||
private $free_busy_map = ['free' => 0, 'busy' => 1, 'out-of-office' => 2, 'outofoffice' => 2, 'tentative' => 3];
|
||||
private $sensitivity_map = ['public' => 0, 'private' => 1, 'confidential' => 2];
|
||||
private $server_timezone;
|
||||
|
||||
private $db_events = 'events';
|
||||
|
@ -77,7 +77,7 @@ class database_driver extends calendar_driver
|
|||
$hidden = array_filter(explode(',', $this->rc->config->get('hidden_calendars', '')));
|
||||
|
||||
if (!empty($this->rc->user->ID)) {
|
||||
$calendar_ids = array();
|
||||
$calendar_ids = [];
|
||||
$result = $this->rc->db->query(
|
||||
"SELECT *, `calendar_id` AS id FROM `{$this->db_calendars}`"
|
||||
. " WHERE `user_id` = ?"
|
||||
|
@ -97,7 +97,7 @@ class database_driver extends calendar_driver
|
|||
$calendar_ids[] = $this->rc->db->quote($arr['calendar_id']);
|
||||
}
|
||||
|
||||
$this->calendar_ids = join(',', $calendar_ids);
|
||||
$this->calendar_ids = implode(',', $calendar_ids);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -112,7 +112,7 @@ class database_driver extends calendar_driver
|
|||
{
|
||||
// attempt to create a default calendar for this user
|
||||
if (empty($this->calendars)) {
|
||||
if ($this->create_calendar(array('name' => 'Default', 'color' => 'cc0000', 'showalarms' => true))) {
|
||||
if ($this->create_calendar(['name' => 'Default', 'color' => 'cc0000', 'showalarms' => true])) {
|
||||
$this->_read_calendars();
|
||||
}
|
||||
}
|
||||
|
@ -132,12 +132,12 @@ class database_driver extends calendar_driver
|
|||
|
||||
// append the virtual birthdays calendar
|
||||
if ($this->rc->config->get('calendar_contact_birthdays', false)) {
|
||||
$prefs = $this->rc->config->get('birthday_calendar', array('color' => '87CEFA'));
|
||||
$prefs = $this->rc->config->get('birthday_calendar', ['color' => '87CEFA']);
|
||||
$hidden = array_filter(explode(',', $this->rc->config->get('hidden_calendars', '')));
|
||||
$id = self::BIRTHDAY_CALENDAR_ID;
|
||||
|
||||
if (!in_array($id, $hidden)) {
|
||||
$calendars[$id] = array(
|
||||
$calendars[$id] = [
|
||||
'id' => $id,
|
||||
'name' => $this->cal->gettext('birthdays'),
|
||||
'listname' => $this->cal->gettext('birthdays'),
|
||||
|
@ -148,7 +148,7 @@ class database_driver extends calendar_driver
|
|||
'editable' => false,
|
||||
'default' => false,
|
||||
'children' => false,
|
||||
);
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -191,7 +191,7 @@ class database_driver extends calendar_driver
|
|||
{
|
||||
// birthday calendar properties are saved in user prefs
|
||||
if ($prop['id'] == self::BIRTHDAY_CALENDAR_ID) {
|
||||
$prefs['birthday_calendar'] = $this->rc->config->get('birthday_calendar', array('color' => '87CEFA'));
|
||||
$prefs['birthday_calendar'] = $this->rc->config->get('birthday_calendar', ['color' => '87CEFA']);
|
||||
if (isset($prop['color'])) {
|
||||
$prefs['birthday_calendar']['color'] = $prop['color'];
|
||||
}
|
||||
|
@ -229,12 +229,11 @@ class database_driver extends calendar_driver
|
|||
|
||||
if ($prop['active']) {
|
||||
unset($hidden[$prop['id']]);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$hidden[$prop['id']] = 1;
|
||||
}
|
||||
|
||||
return $this->rc->user->save_prefs(array('hidden_calendars' => join(',', array_keys($hidden))));
|
||||
return $this->rc->user->save_prefs(['hidden_calendars' => implode(',', array_keys($hidden))]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -270,7 +269,7 @@ class database_driver extends calendar_driver
|
|||
public function search_calendars($query, $source)
|
||||
{
|
||||
// not implemented
|
||||
return array();
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -331,14 +330,14 @@ class database_driver extends calendar_driver
|
|||
strval($event['title']),
|
||||
isset($event['description']) ? strval($event['description']) : '',
|
||||
isset($event['location']) ? strval($event['location']) : '',
|
||||
isset($event['categories']) ? join(',', (array) $event['categories']) : '',
|
||||
isset($event['categories']) ? implode(',', (array) $event['categories']) : '',
|
||||
isset($event['url']) ? strval($event['url']) : '',
|
||||
intval($event['free_busy']),
|
||||
intval($event['priority']),
|
||||
intval($event['sensitivity']),
|
||||
isset($event['status']) ? strval($event['status']) : '',
|
||||
$event['attendees'],
|
||||
isset($event['alarms']) ? $event['alarms'] : null,
|
||||
$event['alarms'] ?? null,
|
||||
$event['notifyat']
|
||||
);
|
||||
|
||||
|
@ -386,117 +385,118 @@ class database_driver extends calendar_driver
|
|||
|
||||
// modify a recurring event, check submitted savemode to do the right things
|
||||
if ($old['recurrence'] || $old['recurrence_id']) {
|
||||
$master = $old['recurrence_id'] ? $this->get_event(array('id' => $old['recurrence_id'])) : $old;
|
||||
$master = $old['recurrence_id'] ? $this->get_event(['id' => $old['recurrence_id']]) : $old;
|
||||
|
||||
// keep saved exceptions (not submitted by the client)
|
||||
if (!empty($old['recurrence']['EXDATE'])) {
|
||||
$event['recurrence']['EXDATE'] = $old['recurrence']['EXDATE'];
|
||||
}
|
||||
|
||||
$savemode = isset($event['_savemode']) ? $event['_savemode'] : null;
|
||||
$savemode = $event['_savemode'] ?? null;
|
||||
switch ($savemode) {
|
||||
case 'new':
|
||||
$event['uid'] = $this->cal->generate_uid();
|
||||
return $this->new_event($event);
|
||||
case 'new':
|
||||
$event['uid'] = $this->cal->generate_uid();
|
||||
return $this->new_event($event);
|
||||
|
||||
case 'current':
|
||||
// save as exception
|
||||
$event['isexception'] = 1;
|
||||
$update_recurring = false;
|
||||
case 'current':
|
||||
// save as exception
|
||||
$event['isexception'] = 1;
|
||||
$update_recurring = false;
|
||||
|
||||
// set exception to first instance (= master)
|
||||
if ($event['id'] == $master['id']) {
|
||||
$event += $old;
|
||||
$event['recurrence_id'] = $master['id'];
|
||||
$event['_instance'] = libcalendaring::recurrence_instance_identifier($old, $master['allday']);
|
||||
$event['isexception'] = 1;
|
||||
$event_id = $this->_insert_event($event);
|
||||
// set exception to first instance (= master)
|
||||
if ($event['id'] == $master['id']) {
|
||||
$event += $old;
|
||||
$event['recurrence_id'] = $master['id'];
|
||||
$event['_instance'] = libcalendaring::recurrence_instance_identifier($old, $master['allday']);
|
||||
$event['isexception'] = 1;
|
||||
$event_id = $this->_insert_event($event);
|
||||
|
||||
return $event_id;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'future':
|
||||
if ($master['id'] != $event['id']) {
|
||||
// set until-date on master event, then save this instance as new recurring event
|
||||
$master['recurrence']['UNTIL'] = clone $event['start'];
|
||||
$master['recurrence']['UNTIL']->sub(new DateInterval('P1D'));
|
||||
unset($master['recurrence']['COUNT']);
|
||||
$update_master = true;
|
||||
|
||||
// if recurrence COUNT, update value to the correct number of future occurences
|
||||
if ($event['recurrence']['COUNT']) {
|
||||
$fromdate = clone $event['start'];
|
||||
$fromdate->setTimezone($this->server_timezone);
|
||||
|
||||
$query = $this->rc->db->query(
|
||||
"SELECT `event_id` FROM `{$this->db_events}`"
|
||||
. " WHERE `calendar_id` IN ({$this->calendar_ids})"
|
||||
. " AND `start` >= ? AND `recurrence_id` = ?",
|
||||
$fromdate->format(self::DB_DATE_FORMAT),
|
||||
$master['id']
|
||||
);
|
||||
|
||||
if ($count = $this->rc->db->num_rows($query)) {
|
||||
$event['recurrence']['COUNT'] = $count;
|
||||
}
|
||||
return $event_id;
|
||||
}
|
||||
|
||||
$update_recurring = true;
|
||||
$event['recurrence_id'] = 0;
|
||||
$event['isexception'] = 0;
|
||||
$event['_instance'] = '';
|
||||
break;
|
||||
}
|
||||
// else: 'future' == 'all' if modifying the master event
|
||||
|
||||
default: // 'all' is default
|
||||
$event['id'] = $master['id'];
|
||||
$event['recurrence_id'] = 0;
|
||||
case 'future':
|
||||
if ($master['id'] != $event['id']) {
|
||||
// set until-date on master event, then save this instance as new recurring event
|
||||
$master['recurrence']['UNTIL'] = clone $event['start'];
|
||||
$master['recurrence']['UNTIL']->sub(new DateInterval('P1D'));
|
||||
unset($master['recurrence']['COUNT']);
|
||||
$update_master = true;
|
||||
|
||||
// use start date from master but try to be smart on time or duration changes
|
||||
$old_start_date = $old['start']->format('Y-m-d');
|
||||
$old_start_time = $old['allday'] ? '' : $old['start']->format('H:i');
|
||||
$old_duration = $old['end']->format('U') - $old['start']->format('U');
|
||||
// if recurrence COUNT, update value to the correct number of future occurences
|
||||
if ($event['recurrence']['COUNT']) {
|
||||
$fromdate = clone $event['start'];
|
||||
$fromdate->setTimezone($this->server_timezone);
|
||||
|
||||
$new_start_date = $event['start']->format('Y-m-d');
|
||||
$new_start_time = $event['allday'] ? '' : $event['start']->format('H:i');
|
||||
$new_duration = $event['end']->format('U') - $event['start']->format('U');
|
||||
$query = $this->rc->db->query(
|
||||
"SELECT `event_id` FROM `{$this->db_events}`"
|
||||
. " WHERE `calendar_id` IN ({$this->calendar_ids})"
|
||||
. " AND `start` >= ? AND `recurrence_id` = ?",
|
||||
$fromdate->format(self::DB_DATE_FORMAT),
|
||||
$master['id']
|
||||
);
|
||||
|
||||
$diff = $old_start_date != $new_start_date || $old_start_time != $new_start_time || $old_duration != $new_duration;
|
||||
$date_shift = $old['start']->diff($event['start']);
|
||||
if ($count = $this->rc->db->num_rows($query)) {
|
||||
$event['recurrence']['COUNT'] = $count;
|
||||
}
|
||||
}
|
||||
|
||||
// shifted or resized
|
||||
if ($diff && ($old_start_date == $new_start_date || $old_duration == $new_duration)) {
|
||||
$event['start'] = $master['start']->add($old['start']->diff($event['start']));
|
||||
$event['end'] = clone $event['start'];
|
||||
$event['end']->add(new DateInterval('PT'.$new_duration.'S'));
|
||||
}
|
||||
// dates did not change, use the ones from master
|
||||
else if ($new_start_date . $new_start_time == $old_start_date . $old_start_time) {
|
||||
$event['start'] = $master['start'];
|
||||
$event['end'] = $master['end'];
|
||||
}
|
||||
$update_recurring = true;
|
||||
$event['recurrence_id'] = 0;
|
||||
$event['isexception'] = 0;
|
||||
$event['_instance'] = '';
|
||||
break;
|
||||
}
|
||||
// else: 'future' == 'all' if modifying the master event
|
||||
|
||||
// adjust recurrence-id when start changed and therefore the entire recurrence chain changes
|
||||
if (is_array($event['recurrence'])
|
||||
&& ($old_start_date != $new_start_date || $old_start_time != $new_start_time)
|
||||
&& ($exceptions = $this->_load_exceptions($old))
|
||||
) {
|
||||
$recurrence_id_format = libcalendaring::recurrence_id_format($event);
|
||||
// no break
|
||||
default: // 'all' is default
|
||||
$event['id'] = $master['id'];
|
||||
$event['recurrence_id'] = 0;
|
||||
|
||||
foreach ($exceptions as $exception) {
|
||||
$recurrence_id = rcube_utils::anytodatetime($exception['_instance'], $old['start']->getTimezone());
|
||||
if (is_a($recurrence_id, 'DateTime')) {
|
||||
$recurrence_id->add($date_shift);
|
||||
$exception['_instance'] = $recurrence_id->format($recurrence_id_format);
|
||||
$this->_update_event($exception, false);
|
||||
// use start date from master but try to be smart on time or duration changes
|
||||
$old_start_date = $old['start']->format('Y-m-d');
|
||||
$old_start_time = $old['allday'] ? '' : $old['start']->format('H:i');
|
||||
$old_duration = $old['end']->format('U') - $old['start']->format('U');
|
||||
|
||||
$new_start_date = $event['start']->format('Y-m-d');
|
||||
$new_start_time = $event['allday'] ? '' : $event['start']->format('H:i');
|
||||
$new_duration = $event['end']->format('U') - $event['start']->format('U');
|
||||
|
||||
$diff = $old_start_date != $new_start_date || $old_start_time != $new_start_time || $old_duration != $new_duration;
|
||||
$date_shift = $old['start']->diff($event['start']);
|
||||
|
||||
// shifted or resized
|
||||
if ($diff && ($old_start_date == $new_start_date || $old_duration == $new_duration)) {
|
||||
$event['start'] = $master['start']->add($old['start']->diff($event['start']));
|
||||
$event['end'] = clone $event['start'];
|
||||
$event['end']->add(new DateInterval('PT' . $new_duration . 'S'));
|
||||
}
|
||||
// dates did not change, use the ones from master
|
||||
elseif ($new_start_date . $new_start_time == $old_start_date . $old_start_time) {
|
||||
$event['start'] = $master['start'];
|
||||
$event['end'] = $master['end'];
|
||||
}
|
||||
|
||||
// adjust recurrence-id when start changed and therefore the entire recurrence chain changes
|
||||
if (is_array($event['recurrence'])
|
||||
&& ($old_start_date != $new_start_date || $old_start_time != $new_start_time)
|
||||
&& ($exceptions = $this->_load_exceptions($old))
|
||||
) {
|
||||
$recurrence_id_format = libcalendaring::recurrence_id_format($event);
|
||||
|
||||
foreach ($exceptions as $exception) {
|
||||
$recurrence_id = rcube_utils::anytodatetime($exception['_instance'], $old['start']->getTimezone());
|
||||
if (is_a($recurrence_id, 'DateTime')) {
|
||||
$recurrence_id->add($date_shift);
|
||||
$exception['_instance'] = $recurrence_id->format($recurrence_id_format);
|
||||
$this->_update_event($exception, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$ret = $event['id']; // return master ID
|
||||
break;
|
||||
$ret = $event['id']; // return master ID
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -527,17 +527,16 @@ class database_driver extends calendar_driver
|
|||
|
||||
// apply changes to master (and all exceptions)
|
||||
if ($event['_savemode'] == 'all' && $event['recurrence_id']) {
|
||||
$update_event = $this->get_event(array('id' => $event['recurrence_id']));
|
||||
$update_event = $this->get_event(['id' => $event['recurrence_id']]);
|
||||
$update_event['_savemode'] = $event['_savemode'];
|
||||
calendar::merge_attendee_data($update_event, $attendees);
|
||||
}
|
||||
|
||||
if ($ret = $this->update_attendees($update_event, $attendees)) {
|
||||
// replace $event with effectively updated event (for iTip reply)
|
||||
if ($ret !== true && $ret != $update_event['id'] && ($new_event = $this->get_event(array('id' => $ret)))) {
|
||||
if ($ret !== true && $ret != $update_event['id'] && ($new_event = $this->get_event(['id' => $ret]))) {
|
||||
$event = $new_event;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$event = $update_event;
|
||||
}
|
||||
}
|
||||
|
@ -583,8 +582,8 @@ class database_driver extends calendar_driver
|
|||
|
||||
// iterate through the list of properties considered 'significant' for scheduling
|
||||
foreach (self::$scheduling_properties as $prop) {
|
||||
$a = isset($old[$prop]) ? $old[$prop] : null;
|
||||
$b = isset($event[$prop]) ? $event[$prop] : null;
|
||||
$a = $old[$prop] ?? null;
|
||||
$b = $event[$prop] ?? null;
|
||||
|
||||
if (!empty($event['allday']) && ($prop == 'start' || $prop == 'end')
|
||||
&& $a instanceof DateTimeInterface
|
||||
|
@ -602,8 +601,7 @@ class database_driver extends calendar_driver
|
|||
// advanced rrule comparison: no rescheduling if series was shortened
|
||||
if (!empty($a['COUNT']) && !empty($b['COUNT']) && $b['COUNT'] < $a['COUNT']) {
|
||||
unset($a['COUNT'], $b['COUNT']);
|
||||
}
|
||||
else if (!empty($a['UNTIL']) && !empty($b['UNTIL']) && $b['UNTIL'] < $a['UNTIL']) {
|
||||
} elseif (!empty($a['UNTIL']) && !empty($b['UNTIL']) && $b['UNTIL'] < $a['UNTIL']) {
|
||||
unset($a['UNTIL'], $b['UNTIL']);
|
||||
}
|
||||
}
|
||||
|
@ -623,8 +621,7 @@ class database_driver extends calendar_driver
|
|||
foreach ($attendees as $i => $attendee) {
|
||||
if ($attendee['role'] == 'ORGANIZER' && $attendee['email'] && in_array(strtolower($attendee['email']), $emails)) {
|
||||
$is_organizer = true;
|
||||
}
|
||||
else if ($attendee['role'] != 'ORGANIZER'
|
||||
} elseif ($attendee['role'] != 'ORGANIZER'
|
||||
&& $attendee['role'] != 'NON-PARTICIPANT'
|
||||
&& $attendee['status'] != 'DELEGATED'
|
||||
) {
|
||||
|
@ -662,8 +659,8 @@ class database_driver extends calendar_driver
|
|||
$free_busy = isset($event['free_busy']) ? strtolower($event['free_busy']) : '';
|
||||
|
||||
$event['_recurrence'] = rtrim($rrule, ';');
|
||||
$event['free_busy'] = isset($this->free_busy_map[$free_busy]) ? $this->free_busy_map[$free_busy] : null;
|
||||
$event['sensitivity'] = isset($this->sensitivity_map[$sensitivity]) ? $this->sensitivity_map[$sensitivity] : 0;
|
||||
$event['free_busy'] = $this->free_busy_map[$free_busy] ?? null;
|
||||
$event['sensitivity'] = $this->sensitivity_map[$sensitivity] ?? 0;
|
||||
$event['all_day'] = !empty($event['allday']) ? 1 : 0;
|
||||
|
||||
if ($event['free_busy'] == 'tentative') {
|
||||
|
@ -680,8 +677,7 @@ class database_driver extends calendar_driver
|
|||
// process event attendees
|
||||
if (!empty($event['attendees'])) {
|
||||
$event['attendees'] = json_encode((array)$event['attendees']);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$event['attendees'] = '';
|
||||
}
|
||||
|
||||
|
@ -711,18 +707,17 @@ class database_driver extends calendar_driver
|
|||
private function _update_event($event, $update_recurring = true)
|
||||
{
|
||||
$event = $this->_save_preprocess($event);
|
||||
$sql_args = array();
|
||||
$set_cols = array('start', 'end', 'all_day', 'recurrence_id', 'isexception', 'sequence',
|
||||
$sql_args = [];
|
||||
$set_cols = ['start', 'end', 'all_day', 'recurrence_id', 'isexception', 'sequence',
|
||||
'title', 'description', 'location', 'categories', 'url', 'free_busy', 'priority',
|
||||
'sensitivity', 'status', 'attendees', 'alarms', 'notifyat'
|
||||
);
|
||||
'sensitivity', 'status', 'attendees', 'alarms', 'notifyat',
|
||||
];
|
||||
|
||||
foreach ($set_cols as $col) {
|
||||
if (!empty($event[$col]) && is_a($event[$col], 'DateTime')) {
|
||||
$sql_args[$col] = $event[$col]->format(self::DB_DATE_FORMAT);
|
||||
}
|
||||
else if (array_key_exists($col, $event)) {
|
||||
$sql_args[$col] = is_array($event[$col]) ? join(',', $event[$col]) : $event[$col];
|
||||
} elseif (array_key_exists($col, $event)) {
|
||||
$sql_args[$col] = is_array($event[$col]) ? implode(',', $event[$col]) : $event[$col];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -790,7 +785,7 @@ class database_driver extends calendar_driver
|
|||
}
|
||||
|
||||
if (!empty($event['recurrence'])) {
|
||||
$exdata = array();
|
||||
$exdata = [];
|
||||
$exceptions = $this->_load_exceptions($event);
|
||||
|
||||
foreach ($exceptions as $exception) {
|
||||
|
@ -828,12 +823,12 @@ class database_driver extends calendar_driver
|
|||
$next_end = clone $next_start;
|
||||
$next_end->add($duration);
|
||||
|
||||
$notify_at = $this->_get_notification(array(
|
||||
$notify_at = $this->_get_notification([
|
||||
'alarms' => !empty($event['alarms']) ? $event['alarms'] : null,
|
||||
'start' => $next_start,
|
||||
'end' => $next_end,
|
||||
'status' => $event['status']
|
||||
));
|
||||
'status' => $event['status'],
|
||||
]);
|
||||
|
||||
$now = $this->rc->db->now();
|
||||
$query = $this->rc->db->query(
|
||||
|
@ -895,7 +890,7 @@ class database_driver extends calendar_driver
|
|||
$instance_id
|
||||
);
|
||||
|
||||
$exceptions = array();
|
||||
$exceptions = [];
|
||||
while (($sql_arr = $this->rc->db->fetch_assoc($result)) && $sql_arr['event_id']) {
|
||||
$exception = $this->_read_postprocess($sql_arr);
|
||||
$instance = $exception['_instance'] ?: $exception['start']->format($exception['allday'] ? 'Ymd' : 'Ymd\THis');
|
||||
|
@ -948,56 +943,57 @@ class database_driver extends calendar_driver
|
|||
|
||||
// read master if deleting a recurring event
|
||||
if ($event['recurrence'] || $event['recurrence_id']) {
|
||||
$master = $event['recurrence_id'] ? $this->get_event(array('id' => $event['recurrence_id'])) : $event;
|
||||
$master = $event['recurrence_id'] ? $this->get_event(['id' => $event['recurrence_id']]) : $event;
|
||||
$savemode = $event['_savemode'];
|
||||
}
|
||||
|
||||
switch ($savemode) {
|
||||
case 'current':
|
||||
// add exception to master event
|
||||
$master['recurrence']['EXDATE'][] = $event['start'];
|
||||
$update_master = true;
|
||||
|
||||
// just delete this single occurence
|
||||
$query = $this->rc->db->query(
|
||||
"DELETE FROM `{$this->db_events}`"
|
||||
. " WHERE `calendar_id` IN ({$this->calendar_ids}) AND `event_id` = ?",
|
||||
$event['id']
|
||||
);
|
||||
break;
|
||||
|
||||
case 'future':
|
||||
if ($master['id'] != $event['id']) {
|
||||
// set until-date on master event
|
||||
$master['recurrence']['UNTIL'] = clone $event['start'];
|
||||
$master['recurrence']['UNTIL']->sub(new DateInterval('P1D'));
|
||||
unset($master['recurrence']['COUNT']);
|
||||
case 'current':
|
||||
// add exception to master event
|
||||
$master['recurrence']['EXDATE'][] = $event['start'];
|
||||
$update_master = true;
|
||||
|
||||
// delete this and all future instances
|
||||
$fromdate = clone $event['start'];
|
||||
$fromdate->setTimezone($this->server_timezone);
|
||||
|
||||
// just delete this single occurence
|
||||
$query = $this->rc->db->query(
|
||||
"DELETE FROM `{$this->db_events}`"
|
||||
. " WHERE `calendar_id` IN ({$this->calendar_ids}) AND `start` >= ? AND `recurrence_id` = ?",
|
||||
$fromdate->format(self::DB_DATE_FORMAT),
|
||||
. " WHERE `calendar_id` IN ({$this->calendar_ids}) AND `event_id` = ?",
|
||||
$event['id']
|
||||
);
|
||||
break;
|
||||
|
||||
case 'future':
|
||||
if ($master['id'] != $event['id']) {
|
||||
// set until-date on master event
|
||||
$master['recurrence']['UNTIL'] = clone $event['start'];
|
||||
$master['recurrence']['UNTIL']->sub(new DateInterval('P1D'));
|
||||
unset($master['recurrence']['COUNT']);
|
||||
$update_master = true;
|
||||
|
||||
// delete this and all future instances
|
||||
$fromdate = clone $event['start'];
|
||||
$fromdate->setTimezone($this->server_timezone);
|
||||
|
||||
$query = $this->rc->db->query(
|
||||
"DELETE FROM `{$this->db_events}`"
|
||||
. " WHERE `calendar_id` IN ({$this->calendar_ids}) AND `start` >= ? AND `recurrence_id` = ?",
|
||||
$fromdate->format(self::DB_DATE_FORMAT),
|
||||
$master['id']
|
||||
);
|
||||
|
||||
$ret = $master['id'];
|
||||
break;
|
||||
}
|
||||
// else: future == all if modifying the master event
|
||||
|
||||
// no break
|
||||
default: // 'all' is default
|
||||
$query = $this->rc->db->query(
|
||||
"DELETE FROM `{$this->db_events}`"
|
||||
. " WHERE (`event_id` = ? OR `recurrence_id` = ?) AND `calendar_id` IN ({$this->calendar_ids})",
|
||||
$master['id'],
|
||||
$master['id']
|
||||
);
|
||||
|
||||
$ret = $master['id'];
|
||||
break;
|
||||
}
|
||||
// else: future == all if modifying the master event
|
||||
|
||||
default: // 'all' is default
|
||||
$query = $this->rc->db->query(
|
||||
"DELETE FROM `{$this->db_events}`"
|
||||
. " WHERE (`event_id` = ? OR `recurrence_id` = ?) AND `calendar_id` IN ({$this->calendar_ids})",
|
||||
$master['id'],
|
||||
$master['id']
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
$success = $this->rc->db->affected_rows($query);
|
||||
|
@ -1048,9 +1044,8 @@ class database_driver extends calendar_driver
|
|||
$calendars[] = $idx;
|
||||
}
|
||||
}
|
||||
$cals = join(',', $calendars);
|
||||
}
|
||||
else {
|
||||
$cals = implode(',', $calendars);
|
||||
} else {
|
||||
$cals = $this->calendar_ids;
|
||||
}
|
||||
|
||||
|
@ -1087,22 +1082,21 @@ class database_driver extends calendar_driver
|
|||
{
|
||||
if (empty($calendars)) {
|
||||
$calendars = array_keys($this->calendars);
|
||||
}
|
||||
else if (!is_array($calendars)) {
|
||||
} elseif (!is_array($calendars)) {
|
||||
$calendars = explode(',', strval($calendars));
|
||||
}
|
||||
|
||||
// only allow to select from calendars of this use
|
||||
$calendar_ids = array_map(array($this->rc->db, 'quote'), array_intersect($calendars, array_keys($this->calendars)));
|
||||
$calendar_ids = array_map([$this->rc->db, 'quote'], array_intersect($calendars, array_keys($this->calendars)));
|
||||
|
||||
// compose (slow) SQL query for searching
|
||||
// FIXME: improve searching using a dedicated col and normalized values
|
||||
$sql_add = '';
|
||||
if ($query) {
|
||||
foreach (array('title','location','description','categories','attendees') as $col) {
|
||||
$sql_query[] = $this->rc->db->ilike($col, '%'.$query.'%');
|
||||
foreach (['title','location','description','categories','attendees'] as $col) {
|
||||
$sql_query[] = $this->rc->db->ilike($col, '%' . $query . '%');
|
||||
}
|
||||
$sql_add .= " AND (" . join(' OR ', $sql_query) . ")";
|
||||
$sql_add .= " AND (" . implode(' OR ', $sql_query) . ")";
|
||||
}
|
||||
|
||||
if (!$virtual) {
|
||||
|
@ -1113,13 +1107,13 @@ class database_driver extends calendar_driver
|
|||
$sql_add .= " AND e.changed >= " . $this->rc->db->quote(date('Y-m-d H:i:s', $modifiedsince));
|
||||
}
|
||||
|
||||
$events = array();
|
||||
$events = [];
|
||||
if (!empty($calendar_ids)) {
|
||||
$result = $this->rc->db->query(
|
||||
"SELECT e.*, (SELECT COUNT(`attachment_id`) FROM `{$this->db_attachments}`"
|
||||
. " WHERE `event_id` = e.event_id OR `event_id` = e.recurrence_id) AS _attachments"
|
||||
. " FROM `{$this->db_events}` e"
|
||||
. " WHERE e.calendar_id IN (" . join(',', $calendar_ids) . ")"
|
||||
. " WHERE e.calendar_id IN (" . implode(',', $calendar_ids) . ")"
|
||||
. " AND e.start <= " . $this->rc->db->fromunixtime($end)
|
||||
. " AND e.end >= " . $this->rc->db->fromunixtime($start)
|
||||
. $sql_add
|
||||
|
@ -1172,7 +1166,7 @@ class database_driver extends calendar_driver
|
|||
public function count_events($calendars, $start, $end = null)
|
||||
{
|
||||
// not implemented
|
||||
return array();
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1197,18 +1191,15 @@ class database_driver extends calendar_driver
|
|||
|
||||
// parse recurrence rule
|
||||
if ($event['recurrence'] && preg_match_all('/([A-Z]+)=([^;]+);?/', $event['recurrence'], $m, PREG_SET_ORDER)) {
|
||||
$event['recurrence'] = array();
|
||||
$event['recurrence'] = [];
|
||||
foreach ($m as $rr) {
|
||||
if (is_numeric($rr[2])) {
|
||||
$rr[2] = intval($rr[2]);
|
||||
}
|
||||
else if ($rr[1] == 'UNTIL') {
|
||||
} elseif ($rr[1] == 'UNTIL') {
|
||||
$rr[2] = date_create($rr[2]);
|
||||
}
|
||||
else if ($rr[1] == 'RDATE') {
|
||||
} elseif ($rr[1] == 'RDATE') {
|
||||
$rr[2] = array_map('date_create', explode(',', $rr[2]));
|
||||
}
|
||||
else if ($rr[1] == 'EXDATE') {
|
||||
} elseif ($rr[1] == 'EXDATE') {
|
||||
$rr[2] = array_map('date_create', explode(',', $rr[2]));
|
||||
}
|
||||
|
||||
|
@ -1235,9 +1226,8 @@ class database_driver extends calendar_driver
|
|||
// decode serialized event attendees
|
||||
if (strlen($event['attendees'])) {
|
||||
$event['attendees'] = $this->unserialize_attendees($event['attendees']);
|
||||
}
|
||||
else {
|
||||
$event['attendees'] = array();
|
||||
} else {
|
||||
$event['attendees'] = [];
|
||||
}
|
||||
|
||||
// decode serialized alarms
|
||||
|
@ -1259,27 +1249,26 @@ class database_driver extends calendar_driver
|
|||
{
|
||||
if (empty($calendars)) {
|
||||
$calendars = array_keys($this->calendars);
|
||||
}
|
||||
else if (!is_array($calendars)) {
|
||||
} elseif (!is_array($calendars)) {
|
||||
$calendars = explode(',', (array) $calendars);
|
||||
}
|
||||
|
||||
// only allow to select from calendars with activated alarms
|
||||
$calendar_ids = array();
|
||||
$calendar_ids = [];
|
||||
foreach ($calendars as $cid) {
|
||||
if ($this->calendars[$cid] && $this->calendars[$cid]['showalarms']) {
|
||||
$calendar_ids[] = $cid;
|
||||
}
|
||||
}
|
||||
|
||||
$calendar_ids = array_map(array($this->rc->db, 'quote'), $calendar_ids);
|
||||
$alarms = array();
|
||||
$calendar_ids = array_map([$this->rc->db, 'quote'], $calendar_ids);
|
||||
$alarms = [];
|
||||
|
||||
if (!empty($calendar_ids)) {
|
||||
$stime = $this->rc->db->fromunixtime($time);
|
||||
$result = $this->rc->db->query(
|
||||
"SELECT * FROM `{$this->db_events}`"
|
||||
. " WHERE `calendar_id` IN (" . join(',', $calendar_ids) . ")"
|
||||
. " WHERE `calendar_id` IN (" . implode(',', $calendar_ids) . ")"
|
||||
. " AND `notifyat` <= $stime AND `end` > $stime"
|
||||
);
|
||||
|
||||
|
@ -1319,11 +1308,9 @@ class database_driver extends calendar_driver
|
|||
{
|
||||
if (isset($attachment['data'])) {
|
||||
$data = $attachment['data'];
|
||||
}
|
||||
else if (!empty($attachment['path'])) {
|
||||
} elseif (!empty($attachment['path'])) {
|
||||
$data = file_get_contents($attachment['path']);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1363,7 +1350,7 @@ class database_driver extends calendar_driver
|
|||
*/
|
||||
public function list_attachments($event)
|
||||
{
|
||||
$attachments = array();
|
||||
$attachments = [];
|
||||
|
||||
if (!empty($this->calendar_ids)) {
|
||||
$result = $this->rc->db->query(
|
||||
|
@ -1486,18 +1473,17 @@ class database_driver extends calendar_driver
|
|||
if ($alarm['trigger'][0] == '@') {
|
||||
try {
|
||||
$valarms[$i]['trigger'] = new DateTime(substr($alarm['trigger'], 1));
|
||||
}
|
||||
catch (Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
unset($valarms[$i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// convert legacy alarms data
|
||||
else if (strlen($alarms)) {
|
||||
list($trigger, $action) = explode(':', $alarms, 2);
|
||||
elseif (strlen($alarms)) {
|
||||
[$trigger, $action] = explode(':', $alarms, 2);
|
||||
if ($trigger = libcalendaring::parse_alarm_value($trigger)) {
|
||||
$valarms = array(array('action' => $action, 'trigger' => $trigger[3] ?: $trigger[0]));
|
||||
$valarms = [['action' => $action, 'trigger' => $trigger[3] ?: $trigger[0]]];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1509,7 +1495,7 @@ class database_driver extends calendar_driver
|
|||
*/
|
||||
private function unserialize_attendees($s_attendees)
|
||||
{
|
||||
$attendees = array();
|
||||
$attendees = [];
|
||||
|
||||
// decode json serialized string
|
||||
if ($s_attendees[0] == '[') {
|
||||
|
@ -1518,9 +1504,9 @@ class database_driver extends calendar_driver
|
|||
// decode the old serialization format
|
||||
else {
|
||||
foreach (explode("\n", $s_attendees) as $line) {
|
||||
$att = array();
|
||||
$att = [];
|
||||
foreach (rcube_utils::explode_quoted_string(';', $line) as $prop) {
|
||||
list($key, $value) = explode("=", $prop);
|
||||
[$key, $value] = explode("=", $prop);
|
||||
$att[strtolower($key)] = stripslashes(trim($value, '""'));
|
||||
}
|
||||
$attendees[] = $att;
|
||||
|
|
|
@ -90,13 +90,13 @@ class kolab_calendar extends kolab_storage_folder_api
|
|||
$this->editable = true;
|
||||
$this->rights = 'lrswikxteav';
|
||||
$this->alarms = true;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$rights = $this->storage->get_myrights();
|
||||
if ($rights && !PEAR::isError($rights)) {
|
||||
$this->rights = $rights;
|
||||
if (strpos($rights, 't') !== false || strpos($rights, 'd') !== false) {
|
||||
$this->editable = strpos($rights, 'i');;
|
||||
$this->editable = strpos($rights, 'i');
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -105,8 +105,7 @@ class kolab_calendar extends kolab_storage_folder_api
|
|||
$prefs = $this->cal->rc->config->get('kolab_calendars', []);
|
||||
if (isset($prefs[$this->id]['showalarms'])) {
|
||||
$this->alarms = $prefs[$this->id]['showalarms'];
|
||||
}
|
||||
else if (isset($prefs[$old_id]['showalarms'])) {
|
||||
} elseif (isset($prefs[$old_id]['showalarms'])) {
|
||||
$this->alarms = $prefs[$old_id]['showalarms'];
|
||||
}
|
||||
}
|
||||
|
@ -216,10 +215,9 @@ class kolab_calendar extends kolab_storage_folder_api
|
|||
$this->events[$id] = $this->_to_driver_event($instance, false, true, $master);
|
||||
}
|
||||
// check for match on the first instance already
|
||||
else if (!empty($master['_instance']) && $master['_instance'] == $instance_id) {
|
||||
elseif (!empty($master['_instance']) && $master['_instance'] == $instance_id) {
|
||||
$this->events[$id] = $master;
|
||||
}
|
||||
else if (!empty($master['recurrence'])) {
|
||||
} elseif (!empty($master['recurrence'])) {
|
||||
$start_date = $master['start'];
|
||||
// For performance reasons we'll get only the specific instance
|
||||
if (($date = substr($id, strlen($master_id) + 1, 8)) && strlen($date) == 8 && is_numeric($date)) {
|
||||
|
@ -274,14 +272,12 @@ class kolab_calendar extends kolab_storage_folder_api
|
|||
// to workaround possible timezone differences
|
||||
try {
|
||||
$start = new DateTime('@' . ($start - 12 * 3600));
|
||||
}
|
||||
catch (Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
$start = new DateTime('@0');
|
||||
}
|
||||
try {
|
||||
$end = new DateTime('@' . ($end + 12 * 3600));
|
||||
}
|
||||
catch (Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
$end = new DateTime('today +10 years');
|
||||
}
|
||||
|
||||
|
@ -373,7 +369,7 @@ class kolab_calendar extends kolab_storage_folder_api
|
|||
$events = array_merge($events, $this->get_recurring_events($record, $start, $end));
|
||||
}
|
||||
// add top-level exceptions (aka loose single occurrences)
|
||||
else if (!empty($record['exceptions'])) {
|
||||
elseif (!empty($record['exceptions'])) {
|
||||
foreach ($record['exceptions'] as $ex) {
|
||||
$component = $this->_to_driver_event($ex, false, false, $record);
|
||||
if ($component['start'] <= $end && $component['end'] >= $start) {
|
||||
|
@ -385,7 +381,7 @@ class kolab_calendar extends kolab_storage_folder_api
|
|||
|
||||
// post-filter all events by fulltext search and partstat values
|
||||
$me = $this;
|
||||
$events = array_filter($events, function($event) use ($words, $partstat_exclude, $user_emails, $me) {
|
||||
$events = array_filter($events, function ($event) use ($words, $partstat_exclude, $user_emails, $me) {
|
||||
// fulltext search
|
||||
if (count($words)) {
|
||||
$hits = 0;
|
||||
|
@ -435,16 +431,14 @@ class kolab_calendar extends kolab_storage_folder_api
|
|||
{
|
||||
// convert to DateTime for comparisons
|
||||
try {
|
||||
$start = new DateTime('@'.$start);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
$start = new DateTime('@' . $start);
|
||||
} catch (Exception $e) {
|
||||
$start = new DateTime('@0');
|
||||
}
|
||||
if ($end) {
|
||||
try {
|
||||
$end = new DateTime('@'.$end);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
$end = new DateTime('@' . $end);
|
||||
} catch (Exception $e) {
|
||||
$end = null;
|
||||
}
|
||||
}
|
||||
|
@ -462,8 +456,7 @@ class kolab_calendar extends kolab_storage_folder_api
|
|||
$query[] = ['tags', '!=', 'x-partstat:' . $email . ':needs-action'];
|
||||
$query[] = ['tags', '!=', 'x-partstat:' . $email . ':declined'];
|
||||
}
|
||||
}
|
||||
else if (is_array($filter_query)) {
|
||||
} elseif (is_array($filter_query)) {
|
||||
$query = array_merge($query, $filter_query);
|
||||
}
|
||||
|
||||
|
@ -493,15 +486,16 @@ class kolab_calendar extends kolab_storage_folder_api
|
|||
$saved = $this->storage->save($object, 'event');
|
||||
|
||||
if (!$saved) {
|
||||
rcube::raise_error([
|
||||
rcube::raise_error(
|
||||
[
|
||||
'code' => 600, 'file' => __FILE__, 'line' => __LINE__,
|
||||
'message' => "Error saving event object to Kolab server"
|
||||
'message' => "Error saving event object to Kolab server",
|
||||
],
|
||||
true, false
|
||||
true,
|
||||
false
|
||||
);
|
||||
$saved = false;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// save links in configuration.relation object
|
||||
if ($this->save_links($event['uid'], $links)) {
|
||||
$object['links'] = $links;
|
||||
|
@ -542,14 +536,15 @@ class kolab_calendar extends kolab_storage_folder_api
|
|||
$saved = $this->storage->save($object, 'event', $old['uid']);
|
||||
|
||||
if (!$saved) {
|
||||
rcube::raise_error([
|
||||
rcube::raise_error(
|
||||
[
|
||||
'code' => 600, 'file' => __FILE__, 'line' => __LINE__,
|
||||
'message' => "Error saving event object to Kolab server"
|
||||
'message' => "Error saving event object to Kolab server",
|
||||
],
|
||||
true, false
|
||||
true,
|
||||
false
|
||||
);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// save links in configuration.relation object
|
||||
if ($this->save_links($event['uid'], $links)) {
|
||||
$object['links'] = $links;
|
||||
|
@ -579,11 +574,13 @@ class kolab_calendar extends kolab_storage_folder_api
|
|||
$deleted = $this->storage->delete(!empty($event['uid']) ? $event['uid'] : $event['id'], $force);
|
||||
|
||||
if (!$deleted) {
|
||||
rcube::raise_error([
|
||||
rcube::raise_error(
|
||||
[
|
||||
'code' => 600, 'file' => __FILE__, 'line' => __LINE__,
|
||||
'message' => sprintf("Error deleting event object '%s' from Kolab server", $event['id'])
|
||||
'message' => sprintf("Error deleting event object '%s' from Kolab server", $event['id']),
|
||||
],
|
||||
true, false
|
||||
true,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -606,11 +603,13 @@ class kolab_calendar extends kolab_storage_folder_api
|
|||
return true;
|
||||
}
|
||||
|
||||
rcube::raise_error([
|
||||
rcube::raise_error(
|
||||
[
|
||||
'code' => 600, 'file' => __FILE__, 'line' => __LINE__,
|
||||
'message' => sprintf("Error undeleting the event object '%s' from the Kolab server", $event['id'])
|
||||
'message' => sprintf("Error undeleting the event object '%s' from the Kolab server", $event['id']),
|
||||
],
|
||||
true, false
|
||||
true,
|
||||
false
|
||||
);
|
||||
|
||||
return false;
|
||||
|
@ -650,8 +649,7 @@ class kolab_calendar extends kolab_storage_folder_api
|
|||
if (empty($event['_formatobj'])) {
|
||||
$rec = $this->storage->get_object(!empty($event['uid']) ? $event['uid'] : $event['id']);
|
||||
$object = $rec['_formatobj'];
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$object = $event['_formatobj'];
|
||||
}
|
||||
|
||||
|
@ -778,8 +776,7 @@ class kolab_calendar extends kolab_storage_folder_api
|
|||
if ($limit && count($events) >= $limit) {
|
||||
return $events;
|
||||
}
|
||||
}
|
||||
else if ($next_event['start'] > $end) {
|
||||
} elseif ($next_event['start'] > $end) {
|
||||
// stop loop if out of range
|
||||
break;
|
||||
}
|
||||
|
@ -825,14 +822,13 @@ class kolab_calendar extends kolab_storage_folder_api
|
|||
$recurrence_id_format = libcalendaring::recurrence_id_format($master_event ? $master_event : $record);
|
||||
if (!$noinst && !empty($record['recurrence']) && empty($record['recurrence_id']) && empty($record['_instance'])) {
|
||||
$record['_instance'] = $record['start']->format($recurrence_id_format);
|
||||
}
|
||||
else if (isset($record['recurrence_date']) && $record['recurrence_date'] instanceof DateTimeInterface) {
|
||||
} elseif (isset($record['recurrence_date']) && $record['recurrence_date'] instanceof DateTimeInterface) {
|
||||
$record['_instance'] = $record['recurrence_date']->format($recurrence_id_format);
|
||||
}
|
||||
|
||||
// clean up exception data
|
||||
if (!empty($record['recurrence']) && !empty($record['recurrence']['EXCEPTIONS'])) {
|
||||
array_walk($record['recurrence']['EXCEPTIONS'], function(&$exception) {
|
||||
array_walk($record['recurrence']['EXCEPTIONS'], function (&$exception) {
|
||||
unset($exception['_mailbox'], $exception['_msguid'], $exception['_formatobj'], $exception['_attachments']);
|
||||
});
|
||||
}
|
||||
|
@ -883,7 +879,7 @@ class kolab_calendar extends kolab_storage_folder_api
|
|||
}
|
||||
|
||||
// remove some internal properties which should not be cached
|
||||
$cleanup_fn = function(&$event) {
|
||||
$cleanup_fn = function (&$event) {
|
||||
unset($event['_savemode'], $event['_fromcalendar'], $event['_identity'], $event['_folder_id'],
|
||||
$event['calendar'], $event['className'], $event['recurrence_id'],
|
||||
$event['attachments'], $event['deleted_attachments']);
|
||||
|
@ -893,7 +889,7 @@ class kolab_calendar extends kolab_storage_folder_api
|
|||
|
||||
// clean up exception data
|
||||
if (!empty($event['exceptions'])) {
|
||||
array_walk($event['exceptions'], function(&$exception) use ($cleanup_fn) {
|
||||
array_walk($event['exceptions'], function (&$exception) use ($cleanup_fn) {
|
||||
unset($exception['_mailbox'], $exception['_msguid'], $exception['_formatobj']);
|
||||
$cleanup_fn($exception);
|
||||
});
|
||||
|
@ -948,13 +944,11 @@ class kolab_calendar extends kolab_storage_folder_api
|
|||
foreach ($prop as $key => $val) {
|
||||
if (is_numeric($key) || is_array($val)) {
|
||||
$out .= self::_complex2string($val);
|
||||
}
|
||||
else if (!in_array($key, $ignorekeys)) {
|
||||
} elseif (!in_array($key, $ignorekeys)) {
|
||||
$out .= $val . ' ';
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (is_string($prop) || is_numeric($prop)) {
|
||||
} elseif (is_string($prop) || is_numeric($prop)) {
|
||||
$out .= $prop . ' ';
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -45,19 +45,19 @@ class kolab_invitation_calendar
|
|||
$this->id = $id;
|
||||
|
||||
switch ($this->id) {
|
||||
case kolab_driver::INVITATIONS_CALENDAR_PENDING:
|
||||
$this->partstats = ['NEEDS-ACTION'];
|
||||
$this->name = $this->cal->gettext('invitationspending');
|
||||
case kolab_driver::INVITATIONS_CALENDAR_PENDING:
|
||||
$this->partstats = ['NEEDS-ACTION'];
|
||||
$this->name = $this->cal->gettext('invitationspending');
|
||||
|
||||
if (!empty($_REQUEST['_quickview'])) {
|
||||
$this->partstats[] = 'TENTATIVE';
|
||||
}
|
||||
break;
|
||||
if (!empty($_REQUEST['_quickview'])) {
|
||||
$this->partstats[] = 'TENTATIVE';
|
||||
}
|
||||
break;
|
||||
|
||||
case kolab_driver::INVITATIONS_CALENDAR_DECLINED:
|
||||
$this->partstats = ['DECLINED'];
|
||||
$this->name = $this->cal->gettext('invitationsdeclined');
|
||||
break;
|
||||
case kolab_driver::INVITATIONS_CALENDAR_DECLINED:
|
||||
$this->partstats = ['DECLINED'];
|
||||
$this->name = $this->cal->gettext('invitationsdeclined');
|
||||
break;
|
||||
}
|
||||
|
||||
// user-specific alarms settings win
|
||||
|
@ -213,8 +213,7 @@ class kolab_invitation_calendar
|
|||
// find the actual folder this event resides in
|
||||
if (!empty($event['_folder_id'])) {
|
||||
$cal = $this->cal->driver->get_calendar($event['_folder_id']);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$cal = null;
|
||||
foreach (kolab_storage::list_folders('', '*', 'event', null) as $foldername) {
|
||||
$cal = $this->_get_calendar($foldername);
|
||||
|
@ -313,7 +312,7 @@ class kolab_invitation_calendar
|
|||
|
||||
$filter = [
|
||||
['tags', '!=', 'x-status:cancelled'],
|
||||
[$subquery, 'OR']
|
||||
[$subquery, 'OR'],
|
||||
];
|
||||
|
||||
// aggregate counts from all calendar folders
|
||||
|
|
|
@ -45,12 +45,10 @@ class kolab_user_calendar extends kolab_calendar
|
|||
if (is_array($user_or_folder)) {
|
||||
$this->userdata = $user_or_folder;
|
||||
$this->storage = new kolab_storage_folder_user($this->userdata['kolabtargetfolder'], '', $this->userdata);
|
||||
}
|
||||
else if ($user_or_folder instanceof kolab_storage_folder_user) {
|
||||
} elseif ($user_or_folder instanceof kolab_storage_folder_user) {
|
||||
$this->storage = $user_or_folder;
|
||||
$this->userdata = $this->storage->ldaprec;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// get user record from LDAP
|
||||
$this->storage = new kolab_storage_folder_user($user_or_folder);
|
||||
$this->userdata = $this->storage->ldaprec;
|
||||
|
@ -187,7 +185,7 @@ class kolab_user_calendar extends kolab_calendar
|
|||
public function get_event($id)
|
||||
{
|
||||
// TODO: implement this
|
||||
return isset($this->events[$id]) ? $this->events[$id] : null;
|
||||
return $this->events[$id] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -221,15 +219,13 @@ class kolab_user_calendar extends kolab_calendar
|
|||
{
|
||||
// convert to DateTime for comparisons
|
||||
try {
|
||||
$start_dt = new DateTime('@'.$start);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
$start_dt = new DateTime('@' . $start);
|
||||
} catch (Exception $e) {
|
||||
$start_dt = new DateTime('@0');
|
||||
}
|
||||
try {
|
||||
$end_dt = new DateTime('@'.$end);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
$end_dt = new DateTime('@' . $end);
|
||||
} catch (Exception $e) {
|
||||
$end_dt = new DateTime('today +10 years');
|
||||
}
|
||||
|
||||
|
@ -238,8 +234,10 @@ class kolab_user_calendar extends kolab_calendar
|
|||
if (!empty($query)) {
|
||||
foreach ($query as $q) {
|
||||
if ($q[0] == 'changed' && $q[1] == '>=') {
|
||||
try { $limit_changed = new DateTime('@'.$q[2]); }
|
||||
catch (Exception $e) { /* ignore */ }
|
||||
try {
|
||||
$limit_changed = new DateTime('@' . $q[2]);
|
||||
} catch (Exception $e) { /* ignore */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -318,13 +316,14 @@ class kolab_user_calendar extends kolab_calendar
|
|||
}
|
||||
|
||||
unset($request, $response);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
rcube::raise_error([
|
||||
} catch (Exception $e) {
|
||||
rcube::raise_error(
|
||||
[
|
||||
'code' => 900, 'file' => __FILE__, 'line' => __LINE__,
|
||||
'message' => "Error fetching free/busy information: " . $e->getMessage()
|
||||
'message' => "Error fetching free/busy information: " . $e->getMessage(),
|
||||
],
|
||||
true, false
|
||||
true,
|
||||
false
|
||||
);
|
||||
|
||||
return false;
|
||||
|
@ -360,7 +359,7 @@ class kolab_user_calendar extends kolab_calendar
|
|||
}
|
||||
|
||||
foreach ($fb['periods'] as $tuple) {
|
||||
list($from, $to, $type) = $tuple;
|
||||
[$from, $to, $type] = $tuple;
|
||||
$event = [
|
||||
'uid' => md5($this->id . $from->format('U') . '/' . $to->format('U')),
|
||||
'calendar' => $this->id,
|
||||
|
@ -372,7 +371,7 @@ class kolab_user_calendar extends kolab_calendar
|
|||
'className' => 'fc-type-freebusy',
|
||||
'organizer' => [
|
||||
'email' => $this->userdata['mail'],
|
||||
'name' => isset($this->userdata['displayname']) ? $this->userdata['displayname'] : null,
|
||||
'name' => $this->userdata['displayname'] ?? null,
|
||||
],
|
||||
];
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ class resources_driver_ldap extends resources_driver
|
|||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
function __construct($cal)
|
||||
public function __construct($cal)
|
||||
{
|
||||
$this->cal = $cal;
|
||||
$this->rc = $cal->rc;
|
||||
|
@ -59,8 +59,7 @@ class resources_driver_ldap extends resources_driver
|
|||
if (isset($query)) {
|
||||
$mode = $searchField == 'owner' ? rcube_addressbook::SEARCH_STRICT : 0;
|
||||
$results = $ldap->search($searchField, $query, $mode, true, true);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$results = $ldap->list_records();
|
||||
}
|
||||
|
||||
|
@ -130,8 +129,7 @@ class resources_driver_ldap extends resources_driver
|
|||
if (!empty($sattr) && $sattr[0] === '{') {
|
||||
$attr = @json_decode($sattr, true);
|
||||
$attributes += $attr;
|
||||
}
|
||||
else if (!empty($sattr) && empty($rec['description'])) {
|
||||
} elseif (!empty($sattr) && empty($rec['description'])) {
|
||||
$rec['description'] = $sattr;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ abstract class resources_driver
|
|||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
function __construct($cal)
|
||||
public function __construct($cal)
|
||||
{
|
||||
$this->cal = $cal;
|
||||
}
|
||||
|
@ -94,7 +94,7 @@ abstract class resources_driver
|
|||
$fblist = $this->cal->driver->get_freebusy_list($rec['email'], $start, $end);
|
||||
if (is_array($fblist)) {
|
||||
foreach ($fblist as $slot) {
|
||||
list($from, $to, $type) = $slot;
|
||||
[$from, $to, $type] = $slot;
|
||||
if ($type == calendar::FREEBUSY_FREE || $type == calendar::FREEBUSY_UNKNOWN) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ class calendar_itip extends libcalendaring_itip
|
|||
/**
|
||||
* Constructor to set text domain to calendar
|
||||
*/
|
||||
function __construct($plugin, $domain = 'calendar')
|
||||
public function __construct($plugin, $domain = 'calendar')
|
||||
{
|
||||
parent::__construct($plugin, $domain);
|
||||
|
||||
|
@ -93,8 +93,7 @@ class calendar_itip extends libcalendaring_itip
|
|||
foreach ($invitation['event']['attendees'] as $i => $attendee) {
|
||||
if ($attendee['role'] == 'ORGANIZER') {
|
||||
$organizer = $attendee;
|
||||
}
|
||||
else if ($attendee['email'] == $email) {
|
||||
} elseif ($attendee['email'] == $email) {
|
||||
// nothing to be done here
|
||||
if ($attendee['status'] == $newstatus) {
|
||||
return true;
|
||||
|
@ -114,11 +113,10 @@ class calendar_itip extends libcalendaring_itip
|
|||
$mailto = !empty($organizer['name']) ? $organizer['name'] : $organizer['email'];
|
||||
$message = $this->plugin->gettext([
|
||||
'name' => 'sentresponseto',
|
||||
'vars' => ['mailto' => $mailto]
|
||||
'vars' => ['mailto' => $mailto],
|
||||
]);
|
||||
$this->rc->output->command('display_message', $message, 'confirmation');
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$this->rc->output->command('display_message', $this->plugin->gettext('itipresponseerror'), 'error');
|
||||
}
|
||||
}
|
||||
|
@ -200,8 +198,8 @@ class calendar_itip extends libcalendaring_itip
|
|||
$this->rc->db->query(
|
||||
"UPDATE $this->db_itipinvitations SET `cancelled` = 1"
|
||||
. " WHERE `event_uid` = ? AND `user_id` = ?",
|
||||
$event_uid,
|
||||
$this->rc->user->ID
|
||||
$event_uid,
|
||||
$this->rc->user->ID
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -230,7 +228,7 @@ class calendar_itip extends libcalendaring_itip
|
|||
*/
|
||||
public function decode_token($token)
|
||||
{
|
||||
list($base, $mail, $hash) = explode('.', $token);
|
||||
[$base, $mail, $hash] = explode('.', $token);
|
||||
|
||||
// validate and return parts
|
||||
if ($mail && $hash && $hash == substr(md5($base . $mail . $this->rc->config->get('des_key')), 0, 6)) {
|
||||
|
|
|
@ -22,13 +22,12 @@
|
|||
*/
|
||||
class calendar_nextcloud_api
|
||||
{
|
||||
|
||||
const PARTICIPANT_OWNER = 1;
|
||||
const PARTICIPANT_MODERATOR = 2;
|
||||
const PARTICIPANT_USER = 3;
|
||||
const PARTICIPANT_GUEST = 4;
|
||||
const PARTICIPANT_PUBLIC = 5;
|
||||
const PARTICIPANT_GUEST_MODERATOR = 6;
|
||||
public const PARTICIPANT_OWNER = 1;
|
||||
public const PARTICIPANT_MODERATOR = 2;
|
||||
public const PARTICIPANT_USER = 3;
|
||||
public const PARTICIPANT_GUEST = 4;
|
||||
public const PARTICIPANT_PUBLIC = 5;
|
||||
public const PARTICIPANT_GUEST_MODERATOR = 6;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -66,8 +65,7 @@ class calendar_nextcloud_api
|
|||
if (!empty($params)) {
|
||||
if ($method == 'POST') {
|
||||
$request->addPostParameter($params);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$request->setUrl($url . '?' . http_build_query($params));
|
||||
}
|
||||
}
|
||||
|
@ -91,14 +89,12 @@ class calendar_nextcloud_api
|
|||
$doc->loadXML($body);
|
||||
$code = $doc->getElementsByTagName('statuscode')->item(0)->textContent;
|
||||
$msg = $doc->getElementsByTagName('message')->item(0)->textContent;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$msg = 'Unknown error';
|
||||
}
|
||||
|
||||
throw new Exception("Nextcloud API Error: [$code] $msg");
|
||||
}
|
||||
catch (Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
rcube::raise_error($e, true, false);
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ class calendar_ui
|
|||
public $calendar;
|
||||
|
||||
|
||||
function __construct($cal)
|
||||
public function __construct($cal)
|
||||
{
|
||||
$this->cal = $cal;
|
||||
$this->rc = $cal->rc;
|
||||
|
@ -52,13 +52,14 @@ class calendar_ui
|
|||
}
|
||||
|
||||
// add taskbar button
|
||||
$this->cal->add_button([
|
||||
$this->cal->add_button(
|
||||
[
|
||||
'command' => 'calendar',
|
||||
'class' => 'button-calendar',
|
||||
'classsel' => 'button-calendar button-selected',
|
||||
'innerclass' => 'button-inner',
|
||||
'label' => 'calendar.calendar',
|
||||
'type' => 'link'
|
||||
'type' => 'link',
|
||||
],
|
||||
'taskbar'
|
||||
);
|
||||
|
@ -115,7 +116,7 @@ class calendar_ui
|
|||
public function addCSS()
|
||||
{
|
||||
$skin_path = $this->cal->local_skin_path();
|
||||
|
||||
|
||||
if (
|
||||
$this->rc->task == 'calendar'
|
||||
&& (!$this->rc->action || in_array($this->rc->action, ['index', 'print']))
|
||||
|
@ -141,8 +142,7 @@ class calendar_ui
|
|||
|
||||
if ($this->rc->task == 'calendar' && $this->rc->action == 'print') {
|
||||
$this->cal->include_script('print.js');
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$this->rc->output->include_script('treelist.js');
|
||||
$this->cal->api->include_script('libkolab/libkolab.js');
|
||||
$this->cal->include_script('calendar_ui.js');
|
||||
|
@ -153,7 +153,7 @@ class calendar_ui
|
|||
/**
|
||||
* Add custom style for the calendar UI
|
||||
*/
|
||||
function calendar_css($attrib = [])
|
||||
public function calendar_css($attrib = [])
|
||||
{
|
||||
$categories = $this->cal->driver->list_categories();
|
||||
$calendars = $this->cal->driver->list_calendars();
|
||||
|
@ -208,7 +208,7 @@ class calendar_ui
|
|||
/**
|
||||
* Generate HTML content of the calendars list (or metadata only)
|
||||
*/
|
||||
function calendar_list($attrib = [], $js_only = false)
|
||||
public function calendar_list($attrib = [], $js_only = false)
|
||||
{
|
||||
$html = '';
|
||||
$jsenv = [];
|
||||
|
@ -223,12 +223,10 @@ class calendar_ui
|
|||
if (!empty($calendars[calendar_driver::BIRTHDAY_CALENDAR_ID])) {
|
||||
$bdaycal = $calendars[calendar_driver::BIRTHDAY_CALENDAR_ID];
|
||||
$calendars = [calendar_driver::BIRTHDAY_CALENDAR_ID => $bdaycal];
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$calendars = []; // clear array for flat listing
|
||||
}
|
||||
}
|
||||
else if (isset($attrib['class'])) {
|
||||
} elseif (isset($attrib['class'])) {
|
||||
// fall-back to flat folder listing
|
||||
$attrib['class'] .= ' flat';
|
||||
}
|
||||
|
@ -241,7 +239,7 @@ class calendar_ui
|
|||
$li_content = $this->calendar_list_item($id, $prop, $jsenv, !empty($attrib['activeonly']));
|
||||
$li_attr = [
|
||||
'id' => 'rcmlical' . $id,
|
||||
'class' => isset($prop['group']) ? $prop['group'] : null,
|
||||
'class' => $prop['group'] ?? null,
|
||||
];
|
||||
|
||||
$html .= html::tag('li', $li_attr, $li_content);
|
||||
|
@ -273,7 +271,9 @@ class calendar_ui
|
|||
$content = $this->calendar_list_item($id, $prop, $jsenv, !empty($attrib['activeonly']));
|
||||
|
||||
if (!empty($folder->children)) {
|
||||
$content .= html::tag('ul', ['style' => $is_collapsed ? "display:none;" : null],
|
||||
$content .= html::tag(
|
||||
'ul',
|
||||
['style' => $is_collapsed ? "display:none;" : null],
|
||||
$this->list_tree_html($folder, $data, $jsenv, $attrib)
|
||||
);
|
||||
}
|
||||
|
@ -304,9 +304,10 @@ class calendar_ui
|
|||
$prop['freebusy'] = $this->cal->driver->freebusy;
|
||||
$prop['attachments'] = $this->cal->driver->attachments;
|
||||
$prop['undelete'] = $this->cal->driver->undelete;
|
||||
$prop['feedurl'] = $this->cal->get_url([
|
||||
$prop['feedurl'] = $this->cal->get_url(
|
||||
[
|
||||
'_cal' => $this->cal->ical_feed_hash($id) . '.ics',
|
||||
'action' => 'feed'
|
||||
'action' => 'feed',
|
||||
]
|
||||
);
|
||||
|
||||
|
@ -315,20 +316,17 @@ class calendar_ui
|
|||
|
||||
if (!empty($prop['title'])) {
|
||||
$title = $prop['title'];
|
||||
}
|
||||
else if ($prop['name'] != $prop['listname'] || strlen($prop['name']) > 25) {
|
||||
} elseif ($prop['name'] != $prop['listname'] || strlen($prop['name']) > 25) {
|
||||
$title = html_entity_decode($prop['name'], ENT_COMPAT, RCUBE_CHARSET);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$title = '';
|
||||
}
|
||||
|
||||
$classes = ['calendar', 'cal-' . asciiwords($id, true)];
|
||||
$classes = ['calendar', 'cal-' . asciiwords($id, true)];
|
||||
|
||||
if (!empty($prop['virtual'])) {
|
||||
$classes[] = 'virtual';
|
||||
}
|
||||
else if (empty($prop['editable'])) {
|
||||
} elseif (empty($prop['editable'])) {
|
||||
$classes[] = 'readonly';
|
||||
}
|
||||
if (!empty($prop['subscribed'])) {
|
||||
|
@ -356,32 +354,38 @@ class calendar_ui
|
|||
$actions = '';
|
||||
|
||||
if (!empty($prop['removable'])) {
|
||||
$actions .= html::a([
|
||||
$actions .= html::a(
|
||||
[
|
||||
'href' => '#',
|
||||
'class' => 'remove',
|
||||
'title' => $this->cal->gettext('removelist')
|
||||
], ' '
|
||||
'title' => $this->cal->gettext('removelist'),
|
||||
],
|
||||
' '
|
||||
);
|
||||
}
|
||||
|
||||
$actions .= html::a([
|
||||
$actions .= html::a(
|
||||
[
|
||||
'href' => '#',
|
||||
'class' => 'quickview',
|
||||
'title' => $this->cal->gettext('quickview'),
|
||||
'role' => 'checkbox',
|
||||
'aria-checked' => 'false'
|
||||
], ''
|
||||
'aria-checked' => 'false',
|
||||
],
|
||||
''
|
||||
);
|
||||
|
||||
if (!isset($prop['subscriptions']) || $prop['subscriptions'] !== false) {
|
||||
if (!empty($prop['subscribed'])) {
|
||||
$actions .= html::a([
|
||||
$actions .= html::a(
|
||||
[
|
||||
'href' => '#',
|
||||
'class' => 'subscribed',
|
||||
'title' => $this->cal->gettext('calendarsubscribe'),
|
||||
'role' => 'checkbox',
|
||||
'aria-checked' => !empty($prop['subscribed']) ? 'true' : 'false'
|
||||
], ' '
|
||||
'aria-checked' => !empty($prop['subscribed']) ? 'true' : 'false',
|
||||
],
|
||||
' '
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -391,13 +395,13 @@ class calendar_ui
|
|||
'name' => '_cal[]',
|
||||
'value' => $id,
|
||||
'checked' => !empty($prop['active']),
|
||||
'aria-labelledby' => $label_id
|
||||
'aria-labelledby' => $label_id,
|
||||
])
|
||||
. html::span('actions', $actions)
|
||||
. html::span(['class' => 'handle', 'style' => "background-color: #$color"], ' ');
|
||||
}
|
||||
|
||||
$content = html::div(join(' ', $classes), $content);
|
||||
$content = html::div(implode(' ', $classes), $content);
|
||||
}
|
||||
|
||||
return $content;
|
||||
|
@ -406,7 +410,7 @@ class calendar_ui
|
|||
/**
|
||||
* Render a HTML for agenda options form
|
||||
*/
|
||||
function agenda_options($attrib = [])
|
||||
public function agenda_options($attrib = [])
|
||||
{
|
||||
$attrib += ['id' => 'agendaoptions'];
|
||||
$attrib['style'] = 'display:none';
|
||||
|
@ -418,8 +422,10 @@ class calendar_ui
|
|||
$select_range->add($days . ' ' . preg_replace('/\(|\)/', '', $this->cal->lib->gettext('days')), $days);
|
||||
}
|
||||
|
||||
$html = html::span('input-group',
|
||||
html::label(['for' => 'agenda-listrange', 'class' => 'input-group-prepend'],
|
||||
$html = html::span(
|
||||
'input-group',
|
||||
html::label(
|
||||
['for' => 'agenda-listrange', 'class' => 'input-group-prepend'],
|
||||
html::span('input-group-text', $this->cal->gettext('listrange'))
|
||||
)
|
||||
. $select_range->show($this->rc->config->get('calendar_agenda_range', $this->cal->defaults['calendar_agenda_range']))
|
||||
|
@ -431,7 +437,7 @@ class calendar_ui
|
|||
/**
|
||||
* Render a HTML select box for calendar selection
|
||||
*/
|
||||
function calendar_select($attrib = [])
|
||||
public function calendar_select($attrib = [])
|
||||
{
|
||||
$attrib['name'] = 'calendar';
|
||||
$attrib['is_escaped'] = true;
|
||||
|
@ -453,7 +459,7 @@ class calendar_ui
|
|||
/**
|
||||
* Render a HTML select box for user identity selection
|
||||
*/
|
||||
function identity_select($attrib = [])
|
||||
public function identity_select($attrib = [])
|
||||
{
|
||||
$attrib['name'] = 'identity';
|
||||
|
||||
|
@ -470,14 +476,14 @@ class calendar_ui
|
|||
/**
|
||||
* Render a HTML select box to select an event category
|
||||
*/
|
||||
function category_select($attrib = [])
|
||||
public function category_select($attrib = [])
|
||||
{
|
||||
$attrib['name'] = 'categories';
|
||||
|
||||
$select = new html_select($attrib);
|
||||
$select->add('---', '');
|
||||
foreach (array_keys((array) $this->cal->driver->list_categories()) as $cat) {
|
||||
$select->add($cat, $cat);
|
||||
$select->add($cat, $cat);
|
||||
}
|
||||
|
||||
return $select->show(null);
|
||||
|
@ -486,7 +492,7 @@ class calendar_ui
|
|||
/**
|
||||
* Render a HTML select box for status property
|
||||
*/
|
||||
function status_select($attrib = [])
|
||||
public function status_select($attrib = [])
|
||||
{
|
||||
$attrib['name'] = 'status';
|
||||
|
||||
|
@ -502,7 +508,7 @@ class calendar_ui
|
|||
/**
|
||||
* Render a HTML select box for free/busy/out-of-office property
|
||||
*/
|
||||
function freebusy_select($attrib = [])
|
||||
public function freebusy_select($attrib = [])
|
||||
{
|
||||
$attrib['name'] = 'freebusy';
|
||||
|
||||
|
@ -519,7 +525,7 @@ class calendar_ui
|
|||
/**
|
||||
* Render a HTML select for event priorities
|
||||
*/
|
||||
function priority_select($attrib = [])
|
||||
public function priority_select($attrib = [])
|
||||
{
|
||||
$attrib['name'] = 'priority';
|
||||
|
||||
|
@ -533,7 +539,7 @@ class calendar_ui
|
|||
$select->add('6 ', '6');
|
||||
$select->add('7 ', '7');
|
||||
$select->add('8 ' . $this->cal->gettext('low'), '8');
|
||||
$select->add('9 ' . $this->cal->gettext('lowest'), '9');
|
||||
$select->add('9 ' . $this->cal->gettext('lowest'), '9');
|
||||
|
||||
return $select->show(null);
|
||||
}
|
||||
|
@ -541,7 +547,7 @@ class calendar_ui
|
|||
/**
|
||||
* Render HTML form for alarm configuration
|
||||
*/
|
||||
function alarm_select($attrib = [])
|
||||
public function alarm_select($attrib = [])
|
||||
{
|
||||
return $this->cal->lib->alarm_select($attrib, $this->cal->driver->alarm_types, $this->cal->driver->alarm_absolute);
|
||||
}
|
||||
|
@ -549,7 +555,7 @@ class calendar_ui
|
|||
/**
|
||||
* Render HTML for attendee notification warning
|
||||
*/
|
||||
function edit_attendees_notify($attrib = [])
|
||||
public function edit_attendees_notify($attrib = [])
|
||||
{
|
||||
$checkbox = new html_checkbox(['name' => '_notify', 'id' => 'edit-attendees-donotify', 'value' => 1, 'class' => 'pretty-checkbox']);
|
||||
return html::div($attrib, html::label(null, $checkbox->show(1) . ' ' . $this->cal->gettext('sendnotifications')));
|
||||
|
@ -558,7 +564,7 @@ class calendar_ui
|
|||
/**
|
||||
* Render HTML for recurrence option to align start date with the recurrence rule
|
||||
*/
|
||||
function edit_recurrence_sync($attrib = [])
|
||||
public function edit_recurrence_sync($attrib = [])
|
||||
{
|
||||
$checkbox = new html_checkbox(['name' => '_start_sync', 'value' => 1, 'class' => 'pretty-checkbox']);
|
||||
return html::div($attrib, html::label(null, $checkbox->show(1) . ' ' . $this->cal->gettext('eventstartsync')));
|
||||
|
@ -567,7 +573,7 @@ class calendar_ui
|
|||
/**
|
||||
* Generate the form for recurrence settings
|
||||
*/
|
||||
function recurring_event_warning($attrib = [])
|
||||
public function recurring_event_warning($attrib = [])
|
||||
{
|
||||
$attrib['id'] = 'edit-recurring-warning';
|
||||
|
||||
|
@ -578,7 +584,8 @@ class calendar_ui
|
|||
. html::label(null, $radio->show('all', ['value' => 'all']) . $this->cal->gettext('allevents')) . ' '
|
||||
. html::label(null, $radio->show('', ['value' => 'new']) . $this->cal->gettext('saveasnew'));
|
||||
|
||||
return html::div($attrib,
|
||||
return html::div(
|
||||
$attrib,
|
||||
html::div('message', $this->cal->gettext('changerecurringeventwarning'))
|
||||
. html::div('savemode', $form)
|
||||
);
|
||||
|
@ -587,7 +594,7 @@ class calendar_ui
|
|||
/**
|
||||
* Form for uploading and importing events
|
||||
*/
|
||||
function events_import_form($attrib = [])
|
||||
public function events_import_form($attrib = [])
|
||||
{
|
||||
if (empty($attrib['id'])) {
|
||||
$attrib['id'] = 'rcmImportForm';
|
||||
|
@ -606,39 +613,48 @@ class calendar_ui
|
|||
'type' => 'file',
|
||||
'name' => '_data',
|
||||
'size' => !empty($attrib['uploadfieldsize']) ? $attrib['uploadfieldsize'] : null,
|
||||
'accept' => $accept
|
||||
'accept' => $accept,
|
||||
]);
|
||||
|
||||
$select = new html_select(['name' => '_range', 'id' => 'event-import-range']);
|
||||
$select->add([
|
||||
$select->add(
|
||||
[
|
||||
$this->cal->gettext('onemonthback'),
|
||||
$this->cal->gettext(['name' => 'nmonthsback', 'vars' => ['nr'=>2]]),
|
||||
$this->cal->gettext(['name' => 'nmonthsback', 'vars' => ['nr'=>3]]),
|
||||
$this->cal->gettext(['name' => 'nmonthsback', 'vars' => ['nr'=>6]]),
|
||||
$this->cal->gettext(['name' => 'nmonthsback', 'vars' => ['nr'=>12]]),
|
||||
$this->cal->gettext(['name' => 'nmonthsback', 'vars' => ['nr' => 2]]),
|
||||
$this->cal->gettext(['name' => 'nmonthsback', 'vars' => ['nr' => 3]]),
|
||||
$this->cal->gettext(['name' => 'nmonthsback', 'vars' => ['nr' => 6]]),
|
||||
$this->cal->gettext(['name' => 'nmonthsback', 'vars' => ['nr' => 12]]),
|
||||
$this->cal->gettext('all'),
|
||||
],
|
||||
['1','2','3','6','12',0]
|
||||
);
|
||||
|
||||
$html = html::div('form-section form-group row',
|
||||
html::label(['class' => 'col-sm-4 col-form-label', 'for' => 'importfile'],
|
||||
$html = html::div(
|
||||
'form-section form-group row',
|
||||
html::label(
|
||||
['class' => 'col-sm-4 col-form-label', 'for' => 'importfile'],
|
||||
rcube::Q($this->rc->gettext('importfromfile'))
|
||||
)
|
||||
. html::div('col-sm-8', $input->show()
|
||||
. html::div(
|
||||
'col-sm-8',
|
||||
$input->show()
|
||||
. html::div('hint', $this->rc->gettext(['name' => 'maxuploadsize', 'vars' => ['size' => $max_filesize]]))
|
||||
)
|
||||
);
|
||||
|
||||
$html .= html::div('form-section form-group row',
|
||||
html::label(['for' => 'event-import-calendar', 'class' => 'col-form-label col-sm-4'],
|
||||
$html .= html::div(
|
||||
'form-section form-group row',
|
||||
html::label(
|
||||
['for' => 'event-import-calendar', 'class' => 'col-form-label col-sm-4'],
|
||||
$this->cal->gettext('calendar')
|
||||
)
|
||||
. html::div('col-sm-8', $this->calendar_select(['name' => 'calendar', 'id' => 'event-import-calendar']))
|
||||
);
|
||||
|
||||
$html .= html::div('form-section form-group row',
|
||||
html::label(['for' => 'event-import-range', 'class' => 'col-form-label col-sm-4'],
|
||||
$html .= html::div(
|
||||
'form-section form-group row',
|
||||
html::label(
|
||||
['for' => 'event-import-range', 'class' => 'col-form-label col-sm-4'],
|
||||
$this->cal->gettext('importrange')
|
||||
)
|
||||
. html::div('col-sm-8', $select->show(1))
|
||||
|
@ -648,26 +664,31 @@ class calendar_ui
|
|||
$this->rc->output->add_label('import');
|
||||
|
||||
return html::tag('p', null, $this->cal->gettext('importtext'))
|
||||
. html::tag('form', [
|
||||
. html::tag(
|
||||
'form',
|
||||
[
|
||||
'action' => $this->rc->url(['task' => 'calendar', 'action' => 'import_events']),
|
||||
'method' => 'post',
|
||||
'enctype' => 'multipart/form-data',
|
||||
'id' => $attrib['id']
|
||||
], $html
|
||||
'id' => $attrib['id'],
|
||||
],
|
||||
$html
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Form to select options for exporting events
|
||||
*/
|
||||
function events_export_form($attrib = [])
|
||||
public function events_export_form($attrib = [])
|
||||
{
|
||||
if (empty($attrib['id'])) {
|
||||
$attrib['id'] = 'rcmExportForm';
|
||||
}
|
||||
|
||||
$html = html::div('form-section form-group row',
|
||||
html::label(['for' => 'event-export-calendar', 'class' => 'col-sm-4 col-form-label'],
|
||||
$html = html::div(
|
||||
'form-section form-group row',
|
||||
html::label(
|
||||
['for' => 'event-export-calendar', 'class' => 'col-sm-4 col-form-label'],
|
||||
$this->cal->gettext('calendar')
|
||||
)
|
||||
. html::div('col-sm-8', $this->calendar_select(['name' => 'calendar', 'id' => 'event-export-calendar', 'class' => 'form-control custom-select']))
|
||||
|
@ -676,10 +697,11 @@ class calendar_ui
|
|||
$select = new html_select([
|
||||
'name' => 'range',
|
||||
'id' => 'event-export-range',
|
||||
'class' => 'form-control custom-select rounded-right'
|
||||
'class' => 'form-control custom-select rounded-right',
|
||||
]);
|
||||
|
||||
$select->add([
|
||||
$select->add(
|
||||
[
|
||||
$this->cal->gettext('all'),
|
||||
$this->cal->gettext('onemonthback'),
|
||||
$this->cal->gettext(['name' => 'nmonthsback', 'vars' => ['nr' => 2]]),
|
||||
|
@ -695,11 +717,13 @@ class calendar_ui
|
|||
'name' => 'start',
|
||||
'size' => 11,
|
||||
'id' => 'event-export-startdate',
|
||||
'style' => 'display:none'
|
||||
'style' => 'display:none',
|
||||
]);
|
||||
|
||||
$html .= html::div('form-section form-group row',
|
||||
html::label(['for' => 'event-export-range', 'class' => 'col-sm-4 col-form-label'],
|
||||
$html .= html::div(
|
||||
'form-section form-group row',
|
||||
html::label(
|
||||
['for' => 'event-export-range', 'class' => 'col-sm-4 col-form-label'],
|
||||
$this->cal->gettext('exportrange')
|
||||
)
|
||||
. html::div('col-sm-8 input-group', $select->show(0) . $startdate->show())
|
||||
|
@ -709,11 +733,13 @@ class calendar_ui
|
|||
'name' => 'attachments',
|
||||
'id' => 'event-export-attachments',
|
||||
'value' => 1,
|
||||
'class' => 'form-check-input pretty-checkbox'
|
||||
'class' => 'form-check-input pretty-checkbox',
|
||||
]);
|
||||
|
||||
$html .= html::div('form-section form-check row',
|
||||
html::label(['for' => 'event-export-attachments', 'class' => 'col-sm-4 col-form-label'],
|
||||
$html .= html::div(
|
||||
'form-section form-check row',
|
||||
html::label(
|
||||
['for' => 'event-export-attachments', 'class' => 'col-sm-4 col-form-label'],
|
||||
$this->cal->gettext('exportattachments')
|
||||
)
|
||||
. html::div('col-sm-8', $checkbox->show(1))
|
||||
|
@ -721,10 +747,12 @@ class calendar_ui
|
|||
|
||||
$this->rc->output->add_gui_object('exportform', $attrib['id']);
|
||||
|
||||
return html::tag('form', $attrib + [
|
||||
return html::tag(
|
||||
'form',
|
||||
$attrib + [
|
||||
'action' => $this->rc->url(['task' => 'calendar', 'action' => 'export_events']),
|
||||
'method' => 'post',
|
||||
'id' => $attrib['id']
|
||||
'id' => $attrib['id'],
|
||||
],
|
||||
$html
|
||||
);
|
||||
|
@ -734,7 +762,7 @@ class calendar_ui
|
|||
* Handler for calendar form template.
|
||||
* The form content could be overriden by the driver
|
||||
*/
|
||||
function calendar_editform($action, $calendar = [])
|
||||
public function calendar_editform($action, $calendar = [])
|
||||
{
|
||||
$this->action = $action;
|
||||
$this->calendar = $calendar;
|
||||
|
@ -751,7 +779,7 @@ class calendar_ui
|
|||
* Handler for calendar form template.
|
||||
* The form content could be overriden by the driver
|
||||
*/
|
||||
function calendarform($attrib)
|
||||
public function calendarform($attrib)
|
||||
{
|
||||
// compose default calendar form fields
|
||||
$input_name = new html_inputfield(['name' => 'name', 'id' => 'calendar-name', 'size' => 20]);
|
||||
|
@ -760,12 +788,12 @@ class calendar_ui
|
|||
$formfields = [
|
||||
'name' => [
|
||||
'label' => $this->cal->gettext('name'),
|
||||
'value' => $input_name->show(isset($this->calendar['name']) ? $this->calendar['name'] : ''),
|
||||
'value' => $input_name->show($this->calendar['name'] ?? ''),
|
||||
'id' => 'calendar-name',
|
||||
],
|
||||
'color' => [
|
||||
'label' => $this->cal->gettext('color'),
|
||||
'value' => $input_color->show(isset($this->calendar['color']) ? $this->calendar['color'] : ''),
|
||||
'value' => $input_color->show($this->calendar['color'] ?? ''),
|
||||
'id' => 'calendar-color',
|
||||
],
|
||||
];
|
||||
|
@ -781,7 +809,9 @@ class calendar_ui
|
|||
}
|
||||
|
||||
// allow driver to extend or replace the form content
|
||||
return html::tag('form', $attrib + ['action' => '#', 'method' => 'get', 'id' => 'calendarpropform'],
|
||||
return html::tag(
|
||||
'form',
|
||||
$attrib + ['action' => '#', 'method' => 'get', 'id' => 'calendarpropform'],
|
||||
$this->cal->driver->calendar_form($this->action, $this->calendar, $formfields)
|
||||
);
|
||||
}
|
||||
|
@ -789,7 +819,7 @@ class calendar_ui
|
|||
/**
|
||||
* Render HTML for attendees table
|
||||
*/
|
||||
function attendees_list($attrib = [])
|
||||
public function attendees_list($attrib = [])
|
||||
{
|
||||
// add "noreply" checkbox to attendees table only
|
||||
$invitations = strpos($attrib['id'], 'attend') !== false;
|
||||
|
@ -803,7 +833,8 @@ class calendar_ui
|
|||
$table->add_header('confirmstate', $this->cal->gettext('confirmstate'));
|
||||
|
||||
if ($invitations) {
|
||||
$table->add_header(['class' => 'invite', 'title' => $this->cal->gettext('sendinvitations')],
|
||||
$table->add_header(
|
||||
['class' => 'invite', 'title' => $this->cal->gettext('sendinvitations')],
|
||||
$invite->show(1)
|
||||
. html::label('edit-attendees-invite', html::span('inner', $this->cal->gettext('sendinvitations')))
|
||||
);
|
||||
|
@ -824,12 +855,12 @@ class calendar_ui
|
|||
/**
|
||||
* Render HTML for attendees adding form
|
||||
*/
|
||||
function attendees_form($attrib = [])
|
||||
public function attendees_form($attrib = [])
|
||||
{
|
||||
$input = new html_inputfield([
|
||||
'name' => 'participant',
|
||||
'id' => 'edit-attendee-name',
|
||||
'class' => 'form-control'
|
||||
'class' => 'form-control',
|
||||
]);
|
||||
$textarea = new html_textarea([
|
||||
'name' => 'comment',
|
||||
|
@ -837,25 +868,27 @@ class calendar_ui
|
|||
'class' => 'form-control',
|
||||
'rows' => 4,
|
||||
'cols' => 55,
|
||||
'title' => $this->cal->gettext('itipcommenttitle')
|
||||
'title' => $this->cal->gettext('itipcommenttitle'),
|
||||
]);
|
||||
|
||||
return html::div($attrib,
|
||||
html::div('form-searchbar',
|
||||
return html::div(
|
||||
$attrib,
|
||||
html::div(
|
||||
'form-searchbar',
|
||||
$input->show()
|
||||
. ' ' .
|
||||
html::tag('input', [
|
||||
'type' => 'button',
|
||||
'class' => 'button',
|
||||
'id' => 'edit-attendee-add',
|
||||
'value' => $this->cal->gettext('addattendee')
|
||||
'value' => $this->cal->gettext('addattendee'),
|
||||
])
|
||||
. ' ' .
|
||||
html::tag('input', [
|
||||
'type' => 'button',
|
||||
'class' => 'button',
|
||||
'id' => 'edit-attendee-schedule',
|
||||
'value' => $this->cal->gettext('scheduletime') . '...'
|
||||
'value' => $this->cal->gettext('scheduletime') . '...',
|
||||
])
|
||||
)
|
||||
. html::p('attendees-commentbox', html::label('edit-attendees-comment', $this->cal->gettext('itipcomment')) . $textarea->show())
|
||||
|
@ -865,26 +898,28 @@ class calendar_ui
|
|||
/**
|
||||
* Render HTML for resources adding form
|
||||
*/
|
||||
function resources_form($attrib = [])
|
||||
public function resources_form($attrib = [])
|
||||
{
|
||||
$input = new html_inputfield(['name' => 'resource', 'id' => 'edit-resource-name', 'class' => 'form-control']);
|
||||
|
||||
return html::div($attrib,
|
||||
html::div('form-searchbar',
|
||||
return html::div(
|
||||
$attrib,
|
||||
html::div(
|
||||
'form-searchbar',
|
||||
$input->show()
|
||||
. ' ' .
|
||||
html::tag('input', [
|
||||
'type' => 'button',
|
||||
'class' => 'button',
|
||||
'id' => 'edit-resource-add',
|
||||
'value' => $this->cal->gettext('addresource')
|
||||
'value' => $this->cal->gettext('addresource'),
|
||||
])
|
||||
. ' ' .
|
||||
html::tag('input', [
|
||||
'type' => 'button',
|
||||
'class' => 'button',
|
||||
'id' => 'edit-resource-find',
|
||||
'value' => $this->cal->gettext('findresources') . '...'
|
||||
'value' => $this->cal->gettext('findresources') . '...',
|
||||
])
|
||||
)
|
||||
);
|
||||
|
@ -893,7 +928,7 @@ class calendar_ui
|
|||
/**
|
||||
* Render HTML for resources list
|
||||
*/
|
||||
function resources_list($attrib = [])
|
||||
public function resources_list($attrib = [])
|
||||
{
|
||||
$attrib += ['id' => 'calendar-resources-list'];
|
||||
|
||||
|
@ -913,14 +948,20 @@ class calendar_ui
|
|||
$this->rc->output->add_gui_object('resourceownerinfo', $attrib['id'] . '-owner');
|
||||
|
||||
// copy address book labels for owner details to client
|
||||
$this->rc->output->add_label('name','firstname','surname','department','jobtitle','email','phone','address');
|
||||
$this->rc->output->add_label('name', 'firstname', 'surname', 'department', 'jobtitle', 'email', 'phone', 'address');
|
||||
|
||||
$table_attrib = ['id','class','style','width','summary','cellpadding','cellspacing','border'];
|
||||
|
||||
return html::tag('table', $attrib, html::tag('tbody', null, ''), $table_attrib)
|
||||
. html::tag('table', ['id' => $attrib['id'] . '-owner', 'style' => 'display:none'] + $attrib,
|
||||
html::tag('thead', null,
|
||||
html::tag('tr', null,
|
||||
. html::tag(
|
||||
'table',
|
||||
['id' => $attrib['id'] . '-owner', 'style' => 'display:none'] + $attrib,
|
||||
html::tag(
|
||||
'thead',
|
||||
null,
|
||||
html::tag(
|
||||
'tr',
|
||||
null,
|
||||
html::tag('td', ['colspan' => 2], rcube::Q($this->cal->gettext('resourceowner')))
|
||||
)
|
||||
)
|
||||
|
@ -948,7 +989,7 @@ class calendar_ui
|
|||
*
|
||||
* @return string HTML code for the gui object
|
||||
*/
|
||||
function resources_search_form($attrib)
|
||||
public function resources_search_form($attrib)
|
||||
{
|
||||
$attrib += [
|
||||
'command' => 'search-resource',
|
||||
|
@ -966,17 +1007,22 @@ class calendar_ui
|
|||
/**
|
||||
*
|
||||
*/
|
||||
function attendees_freebusy_table($attrib = [])
|
||||
public function attendees_freebusy_table($attrib = [])
|
||||
{
|
||||
$table = new html_table(['cols' => 2, 'border' => 0, 'cellspacing' => 0]);
|
||||
$table->add('attendees',
|
||||
$table->add(
|
||||
'attendees',
|
||||
html::tag('h3', 'boxtitle', $this->cal->gettext('tabattendees'))
|
||||
. html::div('timesheader', ' ')
|
||||
. html::div(['id' => 'schedule-attendees-list', 'class' => 'attendees-list'], '')
|
||||
);
|
||||
$table->add('times',
|
||||
html::div('scroll',
|
||||
html::tag('table', ['id' => 'schedule-freebusy-times', 'border' => 0, 'cellspacing' => 0],
|
||||
$table->add(
|
||||
'times',
|
||||
html::div(
|
||||
'scroll',
|
||||
html::tag(
|
||||
'table',
|
||||
['id' => 'schedule-freebusy-times', 'border' => 0, 'cellspacing' => 0],
|
||||
html::tag('thead') . html::tag('tbody')
|
||||
)
|
||||
. html::div(['id' => 'schedule-event-time', 'style' => 'display:none'], ' ')
|
||||
|
@ -989,10 +1035,11 @@ class calendar_ui
|
|||
/**
|
||||
*
|
||||
*/
|
||||
function event_invitebox($attrib = [])
|
||||
public function event_invitebox($attrib = [])
|
||||
{
|
||||
if (!empty($this->cal->event)) {
|
||||
return html::div($attrib,
|
||||
return html::div(
|
||||
$attrib,
|
||||
$this->cal->itip->itip_object_details_table($this->cal->event, $this->cal->itip->gettext('itipinvitation'))
|
||||
. $this->cal->invitestatus
|
||||
);
|
||||
|
@ -1001,7 +1048,7 @@ class calendar_ui
|
|||
return '';
|
||||
}
|
||||
|
||||
function event_rsvp_buttons($attrib = [])
|
||||
public function event_rsvp_buttons($attrib = [])
|
||||
{
|
||||
$actions = ['accepted', 'tentative', 'declined'];
|
||||
|
||||
|
|
|
@ -194,4 +194,3 @@ $labels['birthdays'] = 'Рождени дни';
|
|||
$labels['arialabelcalendarview'] = 'Преглед на календара';
|
||||
$labels['arialabeleventattendees'] = 'Списък с участниците в събитието';
|
||||
$labels['arialabelresourceselection'] = 'Налични ресурси';
|
||||
?>
|
||||
|
|
|
@ -251,4 +251,3 @@ $labels['arialabeleventattendees'] = 'Llista de participants de l\'esdeveniment'
|
|||
$labels['arialabeleventresources'] = 'Llista de recursos de l\'esdeveniment';
|
||||
$labels['arialabelresourcesearchform'] = 'Formulari de cerca de recursos';
|
||||
$labels['arialabelresourceselection'] = 'Recursos disponibles';
|
||||
?>
|
||||
|
|
|
@ -279,4 +279,3 @@ $labels['arialabeleventresources'] = 'Seznam zdrojů události';
|
|||
$labels['arialabelresourcesearchform'] = 'Hledání zdrojů';
|
||||
$labels['arialabelresourceselection'] = 'Dostupné zdroje';
|
||||
$labels['arialabeleventform'] = 'Úprava události';
|
||||
?>
|
||||
|
|
|
@ -285,4 +285,3 @@ $labels['arialabeleventresources'] = 'Ressourceliste for begivenhed';
|
|||
$labels['arialabelresourcesearchform'] = 'Søgeformular for ressourcer';
|
||||
$labels['arialabelresourceselection'] = 'Tilgængelige ressourcer';
|
||||
$labels['arialabeleventform'] = 'Formular til redigering af begivenhed';
|
||||
?>
|
||||
|
|
|
@ -283,4 +283,3 @@ $labels['arialabeleventresources'] = 'Liste der Terminressourcen';
|
|||
$labels['arialabelresourcesearchform'] = 'Suchformular für Ressourcen';
|
||||
$labels['arialabelresourceselection'] = 'Verfügbare Ressourcen';
|
||||
$labels['arialabeleventform'] = 'Ereignisbearbeitungsformular';
|
||||
?>
|
||||
|
|
|
@ -265,4 +265,3 @@ $labels['arialabeleventattendees'] = 'Teilehmerliste';
|
|||
$labels['arialabeleventresources'] = 'Liste der Terminressourcen';
|
||||
$labels['arialabelresourcesearchform'] = 'Suchformular für Ressourcen';
|
||||
$labels['arialabelresourceselection'] = 'Verfügbare Ressourcen';
|
||||
?>
|
||||
|
|
|
@ -265,4 +265,3 @@ $labels['arialabeleventattendees'] = 'Teilehmerliste';
|
|||
$labels['arialabeleventresources'] = 'Liste der Terminressourcen';
|
||||
$labels['arialabelresourcesearchform'] = 'Suchformular für Ressourcen';
|
||||
$labels['arialabelresourceselection'] = 'Verfügbare Ressourcen';
|
||||
?>
|
||||
|
|
|
@ -92,4 +92,3 @@ $labels['availoutofoffice'] = 'Εκτός γραφείου';
|
|||
$labels['tabsummary'] = 'Περίληψη';
|
||||
$labels['savingdata'] = 'Αποθήκευση δεδομένων...';
|
||||
$labels['objectchangelog'] = 'Αλλαγή ιστορικού';
|
||||
?>
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
* For translation see https://www.transifex.com/projects/p/kolab/resource/calendar/
|
||||
*/
|
||||
|
||||
$labels = array();
|
||||
$labels = [];
|
||||
|
||||
// preferences
|
||||
$labels['default_view'] = 'Default view';
|
||||
|
@ -327,4 +327,3 @@ $labels['createtalkroom'] = 'Create Talk room';
|
|||
$labels['talkroomcreating'] = 'Creating a Talk room for the event...';
|
||||
$labels['talkroomcreateerror'] = 'Failed to create a Talk room.';
|
||||
$labels['talkroomname'] = 'Room for an event';
|
||||
?>
|
||||
|
|
|
@ -278,4 +278,3 @@ $labels['arialabeleventresources'] = 'Lista de recursos del evento';
|
|||
$labels['arialabelresourcesearchform'] = 'Formulario de búsqueda de recursos';
|
||||
$labels['arialabelresourceselection'] = 'Recursos disponibles';
|
||||
$labels['arialabeleventform'] = 'Formulario de edición de evento';
|
||||
?>
|
||||
|
|
|
@ -285,4 +285,3 @@ $labels['arialabeleventresources'] = 'Lista de recursos del evento';
|
|||
$labels['arialabelresourcesearchform'] = 'Formulario de búsqueda de recursos';
|
||||
$labels['arialabelresourceselection'] = 'Recursos disponibles';
|
||||
$labels['arialabeleventform'] = 'Formulario de edición de eventos';
|
||||
?>
|
||||
|
|
|
@ -160,4 +160,3 @@ $labels['arialabelcalendarview'] = 'Kalendri vaade';
|
|||
$labels['calendaractions'] = 'Kalendri toimingud';
|
||||
$labels['calendarprops'] = 'Kalendri omadused';
|
||||
$labels['arialabelresourceselection'] = 'Saadaolevad ressursid';
|
||||
?>
|
||||
|
|
|
@ -277,4 +277,3 @@ $labels['arialabeleventresources'] = 'Tapahtuman resurssilista';
|
|||
$labels['arialabelresourcesearchform'] = 'Resurssien hakulomake';
|
||||
$labels['arialabelresourceselection'] = 'Saatavilla olevat resurssit';
|
||||
$labels['arialabeleventform'] = 'Tapahtuman muokkauslomake';
|
||||
?>
|
||||
|
|
|
@ -264,4 +264,3 @@ $labels['arialabeleventattendees'] = 'Liste des participants à l\'événement';
|
|||
$labels['arialabeleventresources'] = 'Liste des ressources de l\'événement';
|
||||
$labels['arialabelresourcesearchform'] = 'Formulaire de recherche des ressources';
|
||||
$labels['arialabelresourceselection'] = 'Ressources disponibles';
|
||||
?>
|
||||
|
|
|
@ -21,4 +21,3 @@ $labels['calendars'] = 'Kalendari';
|
|||
$labels['category'] = 'Kategorija';
|
||||
$labels['categories'] = 'Kategorije';
|
||||
$labels['status-tentative'] = 'Tentative';
|
||||
?>
|
||||
|
|
|
@ -211,4 +211,3 @@ $labels['displaybirthdayscalendar'] = 'Születésnapok megjelenítése';
|
|||
$labels['birthdayscalendarsources'] = 'Alábbi címjegyzékekből:';
|
||||
$labels['birthdayeventtitle'] = '$name születésnapja';
|
||||
$labels['birthdayage'] = '$age éves';
|
||||
?>
|
||||
|
|
|
@ -259,4 +259,3 @@ $labels['arialabeleventattendees'] = 'Lista partecipanti all\'evento';
|
|||
$labels['arialabeleventresources'] = 'Lista risorse dell\'evento';
|
||||
$labels['arialabelresourcesearchform'] = 'Modulo ricerca risorse';
|
||||
$labels['arialabelresourceselection'] = 'Risorse disponibili';
|
||||
?>
|
||||
|
|
|
@ -263,4 +263,3 @@ $labels['arialabeleventattendees'] = 'イベント参加者リスト';
|
|||
$labels['arialabeleventresources'] = 'イベントリソースリスト';
|
||||
$labels['arialabelresourcesearchform'] = 'リソース検索元';
|
||||
$labels['arialabelresourceselection'] = '利用可能なリソース';
|
||||
?>
|
||||
|
|
|
@ -219,4 +219,3 @@ $labels['arialabelcalendarview'] = '캘린더 보기';
|
|||
$labels['arialabelsearchform'] = '일정 검색 폼';
|
||||
$labels['arialabelquicksearchbox'] = '일정 검색 항목';
|
||||
$labels['arialabelcalsearchform'] = '캘린더 검색 폼';
|
||||
?>
|
||||
|
|
|
@ -263,4 +263,3 @@ $labels['arialabeleventattendees'] = 'Dalībnieku saraksts';
|
|||
$labels['arialabeleventresources'] = 'Resursu saraksts';
|
||||
$labels['arialabelresourcesearchform'] = 'Resursu meklēšanas forma';
|
||||
$labels['arialabelresourceselection'] = 'Pieejamie resursi';
|
||||
?>
|
||||
|
|
|
@ -264,4 +264,3 @@ $labels['arialabeleventattendees'] = 'Lijst met deelnemers van activiteit';
|
|||
$labels['arialabeleventresources'] = 'Lijst met resources voor activiteit';
|
||||
$labels['arialabelresourcesearchform'] = 'Zoekformulier voor resources';
|
||||
$labels['arialabelresourceselection'] = 'Beschikbare resources';
|
||||
?>
|
||||
|
|
|
@ -264,4 +264,3 @@ $labels['arialabeleventattendees'] = 'Lista uczestników zdarzenia';
|
|||
$labels['arialabeleventresources'] = 'Lista zasobów zdarzenia';
|
||||
$labels['arialabelresourcesearchform'] = 'Formularz wyszukiwania zasobów';
|
||||
$labels['arialabelresourceselection'] = 'Dostępne zasoby';
|
||||
?>
|
||||
|
|
|
@ -285,4 +285,3 @@ $labels['arialabeleventresources'] = 'Lista zasobów zdarzenia';
|
|||
$labels['arialabelresourcesearchform'] = 'Formularz wyszukiwania zasobów';
|
||||
$labels['arialabelresourceselection'] = 'Dostępne zasoby';
|
||||
$labels['arialabeleventform'] = 'Formularz edycji wydarzenia';
|
||||
?>
|
||||
|
|
|
@ -266,4 +266,3 @@ $labels['arialabeleventattendees'] = 'Lista de participantes do evento';
|
|||
$labels['arialabeleventresources'] = 'Lista de recursos para eventos';
|
||||
$labels['arialabelresourcesearchform'] = 'Formulário de pesquisa de recursos';
|
||||
$labels['arialabelresourceselection'] = 'Recursos disponíveis';
|
||||
?>
|
||||
|
|
|
@ -262,4 +262,3 @@ $labels['arialabeleventattendees'] = 'Lista de participantes do evento';
|
|||
$labels['arialabeleventresources'] = 'Lista de recursos para eventos';
|
||||
$labels['arialabelresourcesearchform'] = 'Quadro de pesquisa de recursos';
|
||||
$labels['arialabelresourceselection'] = 'Recursos disponíveis';
|
||||
?>
|
||||
|
|
|
@ -285,4 +285,3 @@ $labels['arialabeleventresources'] = 'Ресурсы события';
|
|||
$labels['arialabelresourcesearchform'] = 'Форма поиска ресурсов';
|
||||
$labels['arialabelresourceselection'] = 'Доступные ресурсы';
|
||||
$labels['arialabeleventform'] = 'Форма редактирования события';
|
||||
?>
|
||||
|
|
|
@ -79,4 +79,3 @@ $labels['availbusy'] = 'Zaneprázdnený';
|
|||
$labels['availtentative'] = 'Nezáväzne';
|
||||
$labels['availoutofoffice'] = 'Mimo kancelárie';
|
||||
$labels['tabsummary'] = 'Sumár';
|
||||
?>
|
||||
|
|
|
@ -258,4 +258,3 @@ $labels['arialabeleventattendees'] = 'Seznam sodelujočih na dogodku';
|
|||
$labels['arialabeleventresources'] = 'Seznam virov za dogodek';
|
||||
$labels['arialabelresourcesearchform'] = 'Obrazec za iskanje virov';
|
||||
$labels['arialabelresourceselection'] = 'Viri na voljo';
|
||||
?>
|
||||
|
|
|
@ -257,4 +257,3 @@ $labels['arialabeleventattendees'] = 'Händelse deltagarlista';
|
|||
$labels['arialabeleventresources'] = 'Händelse resurslista';
|
||||
$labels['arialabelresourcesearchform'] = 'Resurser sökformulär';
|
||||
$labels['arialabelresourceselection'] = 'Tillgängliga resurser';
|
||||
?>
|
||||
|
|
|
@ -263,4 +263,3 @@ $labels['arialabeleventattendees'] = 'Händelse deltagarlista';
|
|||
$labels['arialabeleventresources'] = 'Händelse resurslista';
|
||||
$labels['arialabelresourcesearchform'] = 'Resurser sökformulär';
|
||||
$labels['arialabelresourceselection'] = 'Tillgängliga resurser';
|
||||
?>
|
||||
|
|
|
@ -244,4 +244,3 @@ $labels['arialabeleventattendees'] = 'รายชื่อผู้เข้า
|
|||
$labels['arialabeleventresources'] = 'รายการทรัพยากรที่ใช้ในเหตุการณ์';
|
||||
$labels['arialabelresourcesearchform'] = 'ฟอร์มค้นหาทรัพยากร';
|
||||
$labels['arialabelresourceselection'] = 'ทรัพยากรที่ยังว่าง';
|
||||
?>
|
||||
|
|
|
@ -212,4 +212,3 @@ $labels['arialabeleventattendees'] = 'Учасники події';
|
|||
$labels['arialabeleventresources'] = 'Ресурси подій';
|
||||
$labels['arialabelresourcesearchform'] = 'Форма пошуку ресурсів';
|
||||
$labels['arialabelresourceselection'] = 'Доступні ресурси';
|
||||
?>
|
||||
|
|
|
@ -120,4 +120,3 @@ $labels['tabsharing'] = '分享';
|
|||
$labels['savingdata'] = '保存数据...';
|
||||
$labels['futurevents'] = '未来';
|
||||
$labels['allevents'] = '全部';
|
||||
?>
|
||||
|
|
|
@ -25,20 +25,20 @@
|
|||
|
||||
class html_converter extends rcube_plugin
|
||||
{
|
||||
private static $replaces = array(
|
||||
private static $replaces = [
|
||||
"<blockquote>" => "<br>&»&<br>",
|
||||
"</blockquote>" => "<br>&«&<br>",
|
||||
"\x02\x03" => "***^^^SIG^^^***",
|
||||
);
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* Plugin initialization.
|
||||
*/
|
||||
function init()
|
||||
public function init()
|
||||
{
|
||||
// register hook to convert HTML to Text
|
||||
$this->add_hook('html2text', array($this, 'html2text'));
|
||||
$this->add_hook('html2text', [$this, 'html2text']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -82,17 +82,17 @@ class html_converter extends rcube_plugin
|
|||
return false;
|
||||
}
|
||||
|
||||
$args = array(
|
||||
$args = [
|
||||
'{path}' => $tmpfname,
|
||||
'{width}' => (int) $p['width'],
|
||||
'{charset}' => $p['charset'],
|
||||
'{links}' => $p['links'] ? 1 : 0,
|
||||
);
|
||||
/*
|
||||
$command = 'links -force-html -no-connect -no-g -codepage {charset}'
|
||||
. ' -aggressive-cache 0 -html-margin 0 -html-numbered-links {links}'
|
||||
. ' -width {width} -dump {path}';
|
||||
*/
|
||||
];
|
||||
/*
|
||||
$command = 'links -force-html -no-connect -no-g -codepage {charset}'
|
||||
. ' -aggressive-cache 0 -html-margin 0 -html-numbered-links {links}'
|
||||
. ' -width {width} -dump {path}';
|
||||
*/
|
||||
$command = 'lynx -force_html -noreferer -nomargins -dont_wrap_pre'
|
||||
. ' -nolist -display_charset={charset} -width={width} -dump {path}';
|
||||
|
||||
|
@ -112,11 +112,11 @@ class html_converter extends rcube_plugin
|
|||
unlink($tmpfname);
|
||||
|
||||
if ($status) {
|
||||
rcube::raise_error(array(
|
||||
rcube::raise_error([
|
||||
'line' => __LINE__,
|
||||
'file' => __FILE__,
|
||||
'message' => "Failed executing: $command (code: $status)"
|
||||
), true, false);
|
||||
'message' => "Failed executing: $command (code: $status)",
|
||||
], true, false);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -142,7 +142,7 @@ class html_converter extends rcube_plugin
|
|||
/**
|
||||
* Post-filtering on plain text content.
|
||||
*/
|
||||
function postfilter($text)
|
||||
public function postfilter($text)
|
||||
{
|
||||
$replaces = self::$replaces;
|
||||
|
||||
|
@ -168,25 +168,21 @@ class html_converter extends rcube_plugin
|
|||
$level++;
|
||||
$last = true;
|
||||
unset($result[$idx]);
|
||||
}
|
||||
else if ($line === $end) {
|
||||
} elseif ($line === $end) {
|
||||
$level--;
|
||||
$last = true;
|
||||
unset($result[$idx]);
|
||||
}
|
||||
else if ($last && !strlen($line)) {
|
||||
} elseif ($last && !strlen($line)) {
|
||||
unset($result[$idx]);
|
||||
$last = false;
|
||||
}
|
||||
else if ($level) {
|
||||
} elseif ($level) {
|
||||
$len = strlen($line);
|
||||
|
||||
if (!$len && isset($result[$idx+1])
|
||||
&& ($result[$idx+1] === $end || $result[$idx+1] === $start)
|
||||
if (!$len && isset($result[$idx + 1])
|
||||
&& ($result[$idx + 1] === $end || $result[$idx + 1] === $start)
|
||||
) {
|
||||
unset($result[$idx]);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$result[$idx] = str_repeat('>', $level) . ($len ? ' ' . $line : '');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
*/
|
||||
|
||||
// available methods/providers. Supported methods are: 'totp','hotp','yubikey'
|
||||
$config['kolab_2fa_drivers'] = array('totp');
|
||||
$config['kolab_2fa_drivers'] = ['totp'];
|
||||
|
||||
// backend for storing 2-factor-auth related per-user settings
|
||||
// available backends are: 'roundcube', 'ldap', 'sql'
|
||||
|
@ -28,9 +28,9 @@ $config['kolab_2fa_storage'] = 'roundcube';
|
|||
|
||||
// additional config options for the above storage backend
|
||||
// here an example for the LDAP backend:
|
||||
$config['kolab_2fa_storage_config'] = array(
|
||||
$config['kolab_2fa_storage_config'] = [
|
||||
'debug' => false,
|
||||
'hosts' => array('localhost'),
|
||||
'hosts' => ['localhost'],
|
||||
'port' => 389,
|
||||
'bind_dn' => 'uid=kolab-auth-service,ou=Special Users,dc=example,dc=org',
|
||||
'bind_pass' => 'Welcome2KolabSystems',
|
||||
|
@ -39,7 +39,7 @@ $config['kolab_2fa_storage_config'] = array(
|
|||
'filter' => '(&(objectClass=ipaToken)(objectclass=ldapSubEntry)(ipatokenOwner=%fu))',
|
||||
'scope' => 'sub',
|
||||
// translates driver properties to LDAP attributes
|
||||
'fieldmap' => array(
|
||||
'fieldmap' => [
|
||||
'label' => 'cn',
|
||||
'id' => 'ipatokenUniqueID',
|
||||
'active' => 'ipatokenDisabled',
|
||||
|
@ -50,49 +50,49 @@ $config['kolab_2fa_storage_config'] = array(
|
|||
'counter' => 'ipatokenHOTPcounter',
|
||||
'digest' => 'ipatokenOTPalgorithm',
|
||||
'digits' => 'ipatokenOTPdigits',
|
||||
),
|
||||
],
|
||||
// LDAP object classes derived from factor IDs (prefix)
|
||||
// will be translated into the %c placeholder
|
||||
'classmap' => array(
|
||||
'classmap' => [
|
||||
'totp:' => 'ipatokenTOTP',
|
||||
'hotp:' => 'ipatokenHOTP',
|
||||
'*' => 'ipaToken',
|
||||
),
|
||||
],
|
||||
// translates property values into LDAP attribute values and vice versa
|
||||
'valuemap' => array(
|
||||
'active' => array(
|
||||
'valuemap' => [
|
||||
'active' => [
|
||||
false => 'TRUE',
|
||||
true => 'FALSE',
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
// specify non-string data types for properties for implicit conversion
|
||||
'attrtypes' => array(
|
||||
'attrtypes' => [
|
||||
'created' => 'datetime',
|
||||
'counter' => 'integer',
|
||||
'digits' => 'integer',
|
||||
),
|
||||
],
|
||||
// apply these default values to factor records if not specified by the drivers
|
||||
'defaults' => array(
|
||||
'defaults' => [
|
||||
'active' => false,
|
||||
// these are required for ipatokenHOTP records and should match the kolab_2fa_hotp parameters
|
||||
'digest' => 'sha1',
|
||||
'digits' => 6,
|
||||
),
|
||||
],
|
||||
// use this LDAP attribute to compose DN values for factor entries
|
||||
'rdn' => 'ipatokenUniqueID',
|
||||
// assign these object classes to new factor entries
|
||||
'objectclass' => array(
|
||||
'objectclass' => [
|
||||
'top',
|
||||
'ipaToken',
|
||||
'%c',
|
||||
'ldapSubEntry',
|
||||
),
|
||||
],
|
||||
// add these roles to the user's LDAP record if key prefix-matches a factor entry
|
||||
'user_roles' => array(
|
||||
'user_roles' => [
|
||||
'totp:' => 'cn=totp-user,dc=example,dc=org',
|
||||
'hotp:' => 'cn=hotp-user,dc=example,dc=org',
|
||||
),
|
||||
);
|
||||
],
|
||||
];
|
||||
|
||||
// force a lookup for active authentication factors for this user.
|
||||
// to be set by another plugin (e.g. kolab_auth based on LDAP roles)
|
||||
|
@ -102,24 +102,24 @@ $config['kolab_2fa_storage_config'] = array(
|
|||
$config['kolab_2fa_timeout'] = 120;
|
||||
|
||||
// configuration parameters for TOTP (uncomment to adjust)
|
||||
$config['kolab_2fa_totp'] = array(
|
||||
$config['kolab_2fa_totp'] = [
|
||||
// 'digits' => 6,
|
||||
// 'interval' => 30,
|
||||
// 'digest' => 'sha1',
|
||||
// 'issuer' => 'Roundcube',
|
||||
);
|
||||
];
|
||||
|
||||
// configuration parameters for HOTP (uncomment to adjust)
|
||||
$config['kolab_2fa_hotp'] = array(
|
||||
$config['kolab_2fa_hotp'] = [
|
||||
// 'digits' => 6,
|
||||
// 'window' => 4,
|
||||
// 'digest' => 'sha1',
|
||||
);
|
||||
];
|
||||
|
||||
// configuration parameters for Yubikey (uncomment to adjust)
|
||||
$config['kolab_2fa_yubikey'] = array(
|
||||
$config['kolab_2fa_yubikey'] = [
|
||||
'clientid' => '123456',
|
||||
'apikey' => '<your-server-api-key>',
|
||||
// 'hosts' => array('api.myhost1.com','api2.myhost.com'),
|
||||
'use_https' => true, // connect via https if set to true
|
||||
);
|
||||
];
|
||||
|
|
|
@ -26,8 +26,8 @@ class kolab_2fa extends rcube_plugin
|
|||
public $task = '(login|settings)';
|
||||
|
||||
protected $login_verified = null;
|
||||
protected $login_factors = array();
|
||||
protected $drivers = array();
|
||||
protected $login_factors = [];
|
||||
protected $drivers = [];
|
||||
protected $storage;
|
||||
|
||||
/**
|
||||
|
@ -36,7 +36,7 @@ class kolab_2fa extends rcube_plugin
|
|||
public function init()
|
||||
{
|
||||
$this->load_config();
|
||||
$this->add_hook('startup', array($this, 'startup'));
|
||||
$this->add_hook('startup', [$this, 'startup']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -48,24 +48,23 @@ class kolab_2fa extends rcube_plugin
|
|||
|
||||
// register library namespace to autoloader
|
||||
$loader = include(INSTALL_PATH . 'vendor/autoload.php');
|
||||
$loader->set('Kolab2FA', array($this->home . '/lib'));
|
||||
$loader->set('Kolab2FA', [$this->home . '/lib']);
|
||||
|
||||
if ($args['task'] === 'login' && $this->api->output) {
|
||||
$this->add_texts('localization/', false);
|
||||
$this->add_hook('authenticate', array($this, 'authenticate'));
|
||||
$this->add_hook('authenticate', [$this, 'authenticate']);
|
||||
|
||||
// process 2nd factor auth step after regular login
|
||||
if ($args['action'] === 'plugin.kolab-2fa-login' /* || !empty($_SESSION['kolab_2fa_factors']) */) {
|
||||
return $this->login_verify($args);
|
||||
}
|
||||
}
|
||||
else if ($args['task'] === 'settings') {
|
||||
} elseif ($args['task'] === 'settings') {
|
||||
$this->add_texts('localization/', !$this->api->output->ajax_call);
|
||||
$this->add_hook('settings_actions', array($this, 'settings_actions'));
|
||||
$this->register_action('plugin.kolab-2fa', array($this, 'settings_view'));
|
||||
$this->register_action('plugin.kolab-2fa-data', array($this, 'settings_data'));
|
||||
$this->register_action('plugin.kolab-2fa-save', array($this, 'settings_save'));
|
||||
$this->register_action('plugin.kolab-2fa-verify', array($this, 'settings_verify'));
|
||||
$this->add_hook('settings_actions', [$this, 'settings_actions']);
|
||||
$this->register_action('plugin.kolab-2fa', [$this, 'settings_view']);
|
||||
$this->register_action('plugin.kolab-2fa-data', [$this, 'settings_data']);
|
||||
$this->register_action('plugin.kolab-2fa-save', [$this, 'settings_save']);
|
||||
$this->register_action('plugin.kolab-2fa-verify', [$this, 'settings_verify']);
|
||||
}
|
||||
|
||||
return $args;
|
||||
|
@ -98,8 +97,7 @@ class kolab_2fa extends rcube_plugin
|
|||
if (!empty($username_domain[$hostname])) {
|
||||
$domain = $username_domain[$hostname];
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$domain = $username_domain;
|
||||
}
|
||||
|
||||
|
@ -111,7 +109,7 @@ class kolab_2fa extends rcube_plugin
|
|||
$username = substr($username, 0, $pos) . '@' . $domain;
|
||||
}
|
||||
// just add domain if not specified
|
||||
else if ($pos === false) {
|
||||
elseif ($pos === false) {
|
||||
$username .= '@' . $domain;
|
||||
}
|
||||
}
|
||||
|
@ -122,28 +120,27 @@ class kolab_2fa extends rcube_plugin
|
|||
if ($login_lc) {
|
||||
if ($login_lc == 2 || $login_lc === true) {
|
||||
$username = mb_strtolower($username);
|
||||
}
|
||||
else if (strpos($username, '@')) {
|
||||
} elseif (strpos($username, '@')) {
|
||||
// lowercase domain name
|
||||
list($local, $domain) = explode('@', $username);
|
||||
[$local, $domain] = explode('@', $username);
|
||||
$username = $local . '@' . mb_strtolower($domain);
|
||||
}
|
||||
}
|
||||
|
||||
// 2a. let plugins provide the list of active authentication factors
|
||||
$lookup = $rcmail->plugins->exec_hook('kolab_2fa_lookup', array(
|
||||
$lookup = $rcmail->plugins->exec_hook('kolab_2fa_lookup', [
|
||||
'user' => $username,
|
||||
'host' => $hostname,
|
||||
'factors' => null,
|
||||
'check' => $rcmail->config->get('kolab_2fa_check', true),
|
||||
));
|
||||
]);
|
||||
|
||||
$factors = [];
|
||||
if (isset($lookup['factors'])) {
|
||||
$factors = (array)$lookup['factors'];
|
||||
}
|
||||
// 2b. check storage if this user has 2FA enabled
|
||||
else if ($lookup['check'] !== false && ($storage = $this->get_storage($username))) {
|
||||
elseif ($lookup['check'] !== false && ($storage = $this->get_storage($username))) {
|
||||
$factors = (array)$storage->enumerate();
|
||||
}
|
||||
|
||||
|
@ -174,7 +171,7 @@ class kolab_2fa extends rcube_plugin
|
|||
{
|
||||
// replace handler for login form
|
||||
$this->login_factors = array_values($factors);
|
||||
$this->api->output->add_handler('loginform', array($this, 'auth_form'));
|
||||
$this->api->output->add_handler('loginform', [$this, 'auth_form']);
|
||||
|
||||
// focus the code input field on load
|
||||
$this->api->output->add_script('$("input.kolab2facode").first().select();', 'docready');
|
||||
|
@ -202,7 +199,7 @@ class kolab_2fa extends rcube_plugin
|
|||
|
||||
// try to verify each configured factor
|
||||
foreach ($factors as $factor) {
|
||||
list($method) = explode(':', $factor, 2);
|
||||
[$method] = explode(':', $factor, 2);
|
||||
|
||||
// verify the submitted code
|
||||
$code = rcube_utils::get_input_value("_${nonce}_${method}", rcube_utils::INPUT_POST);
|
||||
|
@ -252,8 +249,7 @@ class kolab_2fa extends rcube_plugin
|
|||
try {
|
||||
// verify the submitted code
|
||||
return $driver->verify($code, $_SESSION['kolab_2fa_time']);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
rcube::raise_error($e, true, false);
|
||||
}
|
||||
}
|
||||
|
@ -264,26 +260,27 @@ class kolab_2fa extends rcube_plugin
|
|||
/**
|
||||
* Render 2nd factor authentication form in place of the regular login form
|
||||
*/
|
||||
public function auth_form($attrib = array())
|
||||
public function auth_form($attrib = [])
|
||||
{
|
||||
$form_name = !empty($attrib['form']) ? $attrib['form'] : 'form';
|
||||
$nonce = $_SESSION['kolab_2fa_nonce'];
|
||||
|
||||
$methods = array_unique(array_map(function($factor) {
|
||||
list($method, $id) = explode(':', $factor);
|
||||
$methods = array_unique(array_map(
|
||||
function ($factor) {
|
||||
[$method, $id] = explode(':', $factor);
|
||||
return $method;
|
||||
},
|
||||
$this->login_factors
|
||||
));
|
||||
|
||||
// forward these values as the regular login screen would submit them
|
||||
$input_task = new html_hiddenfield(array('name' => '_task', 'value' => 'login'));
|
||||
$input_action = new html_hiddenfield(array('name' => '_action', 'value' => 'plugin.kolab-2fa-login'));
|
||||
$input_tzone = new html_hiddenfield(array('name' => '_timezone', 'id' => 'rcmlogintz', 'value' => rcube_utils::get_input_value('_timezone', rcube_utils::INPUT_POST)));
|
||||
$input_url = new html_hiddenfield(array('name' => '_url', 'id' => 'rcmloginurl', 'value' => rcube_utils::get_input_value('_url', rcube_utils::INPUT_POST)));
|
||||
$input_task = new html_hiddenfield(['name' => '_task', 'value' => 'login']);
|
||||
$input_action = new html_hiddenfield(['name' => '_action', 'value' => 'plugin.kolab-2fa-login']);
|
||||
$input_tzone = new html_hiddenfield(['name' => '_timezone', 'id' => 'rcmlogintz', 'value' => rcube_utils::get_input_value('_timezone', rcube_utils::INPUT_POST)]);
|
||||
$input_url = new html_hiddenfield(['name' => '_url', 'id' => 'rcmloginurl', 'value' => rcube_utils::get_input_value('_url', rcube_utils::INPUT_POST)]);
|
||||
|
||||
// create HTML table with two cols
|
||||
$table = new html_table(array('cols' => 2));
|
||||
$table = new html_table(['cols' => 2]);
|
||||
$required = count($methods) > 1 ? null : 'required';
|
||||
$row = 0;
|
||||
|
||||
|
@ -297,14 +294,14 @@ class kolab_2fa extends rcube_plugin
|
|||
}
|
||||
|
||||
$field_id = "rcmlogin2fa$method";
|
||||
$input_code = new html_inputfield(array(
|
||||
$input_code = new html_inputfield([
|
||||
'name' => "_${nonce}_${method}",
|
||||
'class' => 'kolab2facode',
|
||||
'id' => $field_id,
|
||||
'required' => $required,
|
||||
'autocomplete' => 'off',
|
||||
'data-icon' => 'key' // for Elastic
|
||||
) + $attrib);
|
||||
'data-icon' => 'key', // for Elastic
|
||||
] + $attrib);
|
||||
$table->add('title', html::label($field_id, html::quote($this->gettext($method))));
|
||||
$table->add('input', $input_code->show(''));
|
||||
}
|
||||
|
@ -317,17 +314,19 @@ class kolab_2fa extends rcube_plugin
|
|||
|
||||
// add submit button
|
||||
if (rcube_utils::get_boolean($attrib['submit'])) {
|
||||
$out .= html::p('formbuttons', html::tag('button', array(
|
||||
$out .= html::p(
|
||||
'formbuttons',
|
||||
html::tag('button', [
|
||||
'type' => 'submit',
|
||||
'id' => 'rcmloginsubmit',
|
||||
'class' => 'button mainaction save',
|
||||
), $this->gettext('continue'))
|
||||
], $this->gettext('continue'))
|
||||
);
|
||||
}
|
||||
|
||||
// surround html output with a form tag
|
||||
if (empty($attrib['form'])) {
|
||||
$out = $this->api->output->form_tag(array('name' => $form_name, 'method' => 'post'), $out);
|
||||
$out = $this->api->output->form_tag(['name' => $form_name, 'method' => 'post'], $out);
|
||||
}
|
||||
|
||||
return $out;
|
||||
|
@ -341,7 +340,7 @@ class kolab_2fa extends rcube_plugin
|
|||
*/
|
||||
public function get_driver($factor)
|
||||
{
|
||||
list($method) = explode(':', $factor, 2);
|
||||
[$method] = explode(':', $factor, 2);
|
||||
|
||||
$rcmail = rcmail::get_instance();
|
||||
|
||||
|
@ -349,7 +348,7 @@ class kolab_2fa extends rcube_plugin
|
|||
return $this->drivers[$factor];
|
||||
}
|
||||
|
||||
$config = $rcmail->config->get('kolab_2fa_' . $method, array());
|
||||
$config = $rcmail->config->get('kolab_2fa_' . $method, []);
|
||||
|
||||
// use product name as "issuer""
|
||||
if (empty($config['issuer'])) {
|
||||
|
@ -370,18 +369,20 @@ class kolab_2fa extends rcube_plugin
|
|||
|
||||
$this->drivers[$factor] = $driver;
|
||||
return $driver;
|
||||
}
|
||||
catch (Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
$error = strval($e);
|
||||
}
|
||||
|
||||
rcube::raise_error(array(
|
||||
rcube::raise_error(
|
||||
[
|
||||
'code' => 600,
|
||||
'type' => 'php',
|
||||
'file' => __FILE__,
|
||||
'line' => __LINE__,
|
||||
'message' => $error),
|
||||
true, false);
|
||||
'message' => $error],
|
||||
true,
|
||||
false
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -396,7 +397,7 @@ class kolab_2fa extends rcube_plugin
|
|||
try {
|
||||
$this->storage = \Kolab2FA\Storage\Base::factory(
|
||||
$rcmail->config->get('kolab_2fa_storage', 'roundcube'),
|
||||
$rcmail->config->get('kolab_2fa_storage_config', array())
|
||||
$rcmail->config->get('kolab_2fa_storage_config', [])
|
||||
);
|
||||
|
||||
$this->storage->set_username($for);
|
||||
|
@ -406,17 +407,19 @@ class kolab_2fa extends rcube_plugin
|
|||
if (!empty($_SESSION['kolab_dn'])) {
|
||||
$this->storage->userdn = $_SESSION['kolab_dn'];
|
||||
}
|
||||
}
|
||||
catch (Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
$this->storage = false;
|
||||
|
||||
rcube::raise_error(array(
|
||||
rcube::raise_error(
|
||||
[
|
||||
'code' => 600,
|
||||
'type' => 'php',
|
||||
'file' => __FILE__,
|
||||
'line' => __LINE__,
|
||||
'message' => $e->getMessage()),
|
||||
true, false);
|
||||
'message' => $e->getMessage()],
|
||||
true,
|
||||
false
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -429,13 +432,13 @@ class kolab_2fa extends rcube_plugin
|
|||
public function settings_actions($args)
|
||||
{
|
||||
// register as settings action
|
||||
$args['actions'][] = array(
|
||||
$args['actions'][] = [
|
||||
'action' => 'plugin.kolab-2fa',
|
||||
'class' => 'twofactorauth',
|
||||
'label' => 'settingslist',
|
||||
'title' => 'settingstitle',
|
||||
'domain' => 'kolab_2fa',
|
||||
);
|
||||
];
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
@ -445,16 +448,16 @@ class kolab_2fa extends rcube_plugin
|
|||
*/
|
||||
public function settings_view()
|
||||
{
|
||||
$this->register_handler('plugin.settingsform', array($this, 'settings_form'));
|
||||
$this->register_handler('plugin.settingslist', array($this, 'settings_list'));
|
||||
$this->register_handler('plugin.factoradder', array($this, 'settings_factoradder'));
|
||||
$this->register_handler('plugin.highsecuritydialog', array($this, 'settings_highsecuritydialog'));
|
||||
$this->register_handler('plugin.settingsform', [$this, 'settings_form']);
|
||||
$this->register_handler('plugin.settingslist', [$this, 'settings_list']);
|
||||
$this->register_handler('plugin.factoradder', [$this, 'settings_factoradder']);
|
||||
$this->register_handler('plugin.highsecuritydialog', [$this, 'settings_highsecuritydialog']);
|
||||
|
||||
$this->include_script('kolab2fa.js');
|
||||
$this->include_stylesheet($this->local_skin_path() . '/kolab2fa.css');
|
||||
|
||||
$this->api->output->set_env('session_secured', $this->check_secure_mode());
|
||||
$this->api->output->add_label('save','cancel');
|
||||
$this->api->output->add_label('save', 'cancel');
|
||||
$this->api->output->set_pagetitle($this->gettext('settingstitle'));
|
||||
$this->api->output->send('kolab_2fa.config');
|
||||
}
|
||||
|
@ -470,7 +473,7 @@ class kolab_2fa extends rcube_plugin
|
|||
|
||||
$select = new html_select($attrib);
|
||||
$select->add($this->gettext('addfactor') . '...', '');
|
||||
foreach ((array)$rcmail->config->get('kolab_2fa_drivers', array()) as $method) {
|
||||
foreach ((array)$rcmail->config->get('kolab_2fa_drivers', []) as $method) {
|
||||
$select->add($this->gettext($method), $method);
|
||||
}
|
||||
|
||||
|
@ -480,10 +483,10 @@ class kolab_2fa extends rcube_plugin
|
|||
/**
|
||||
* Render a list of active factor this user has configured
|
||||
*/
|
||||
public function settings_list($attrib = array())
|
||||
public function settings_list($attrib = [])
|
||||
{
|
||||
$attrib['id'] = 'kolab2fa-factors';
|
||||
$table = new html_table(array('cols' => 3));
|
||||
$table = new html_table(['cols' => 3]);
|
||||
|
||||
$table->add_header('name', $this->gettext('factor'));
|
||||
$table->add_header('created', $this->gettext('created'));
|
||||
|
@ -495,28 +498,28 @@ class kolab_2fa extends rcube_plugin
|
|||
/**
|
||||
* Render the settings form template object
|
||||
*/
|
||||
public function settings_form($attrib = array())
|
||||
public function settings_form($attrib = [])
|
||||
{
|
||||
$rcmail = rcmail::get_instance();
|
||||
$storage = $this->get_storage($rcmail->get_user_name());
|
||||
$factors = $storage ? (array)$storage->enumerate() : array();
|
||||
$drivers = (array)$rcmail->config->get('kolab_2fa_drivers', array());
|
||||
$factors = $storage ? (array)$storage->enumerate() : [];
|
||||
$drivers = (array)$rcmail->config->get('kolab_2fa_drivers', []);
|
||||
$out = '';
|
||||
$env_methods = array();
|
||||
$env_methods = [];
|
||||
|
||||
foreach ($drivers as $j => $method) {
|
||||
$out .= $this->settings_factor($method, $attrib);
|
||||
$env_methods[$method] = array(
|
||||
$env_methods[$method] = [
|
||||
'name' => $this->gettext($method),
|
||||
'active' => 0,
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
$me = $this;
|
||||
$factors = array_combine(
|
||||
$factors,
|
||||
array_map(function($id) use ($me, &$env_methods) {
|
||||
$props = array('id' => $id);
|
||||
array_map(function ($id) use ($me, &$env_methods) {
|
||||
$props = ['id' => $id];
|
||||
|
||||
if ($driver = $me->get_driver($id)) {
|
||||
$props += $this->format_props($driver->props());
|
||||
|
@ -532,7 +535,7 @@ class kolab_2fa extends rcube_plugin
|
|||
$this->api->output->set_env('kolab_2fa_methods', $env_methods);
|
||||
$this->api->output->set_env('kolab_2fa_factors', !empty($factors) ? $factors : null);
|
||||
|
||||
return html::div(array('id' => 'kolab2fapropform'), $out);
|
||||
return html::div(['id' => 'kolab2fapropform'], $out);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -542,10 +545,10 @@ class kolab_2fa extends rcube_plugin
|
|||
{
|
||||
$out = '';
|
||||
$rcmail = rcmail::get_instance();
|
||||
$attrib += array('class' => 'propform');
|
||||
$attrib += ['class' => 'propform'];
|
||||
|
||||
if ($driver = $this->get_driver($method)) {
|
||||
$table = new html_table(array('cols' => 2, 'class' => $attrib['class']));
|
||||
$table = new html_table(['cols' => 2, 'class' => $attrib['class']]);
|
||||
|
||||
foreach ($driver->props() as $field => $prop) {
|
||||
if (!$prop['editable']) {
|
||||
|
@ -555,20 +558,20 @@ class kolab_2fa extends rcube_plugin
|
|||
switch ($prop['type']) {
|
||||
case 'boolean':
|
||||
case 'checkbox':
|
||||
$input = new html_checkbox(array('value' => '1'));
|
||||
$input = new html_checkbox(['value' => '1']);
|
||||
break;
|
||||
|
||||
case 'enum':
|
||||
case 'select':
|
||||
$input = new html_select(array('disabled' => !empty($prop['readonly'])));
|
||||
$input->add(array_map(array($this, 'gettext'), $prop['options']), $prop['options']);
|
||||
$input = new html_select(['disabled' => !empty($prop['readonly'])]);
|
||||
$input->add(array_map([$this, 'gettext'], $prop['options']), $prop['options']);
|
||||
break;
|
||||
|
||||
default:
|
||||
$input = new html_inputfield(array(
|
||||
$input = new html_inputfield([
|
||||
'size' => !empty($prop['size']) ? $prop['size'] : 30,
|
||||
'disabled' => empty($prop['editable'])
|
||||
));
|
||||
'disabled' => empty($prop['editable']),
|
||||
]);
|
||||
}
|
||||
|
||||
$explain_label = $field . 'explain' . $method;
|
||||
|
@ -576,38 +579,44 @@ class kolab_2fa extends rcube_plugin
|
|||
|
||||
$field_id = 'rcmk2fa' . $method . $field;
|
||||
$table->add('title', html::label($field_id, $this->gettext($field)));
|
||||
$table->add(null, $input->show('', array('id' => $field_id, 'name' => "_prop[$field]")) . $explain_html);
|
||||
$table->add(null, $input->show('', ['id' => $field_id, 'name' => "_prop[$field]"]) . $explain_html);
|
||||
}
|
||||
|
||||
// add row for displaying the QR code
|
||||
if (method_exists($driver, 'get_provisioning_uri')) {
|
||||
$gif = 'data:image/gif;base64,R0lGODlhDwAPAIAAAMDAwAAAACH5BAEAAAAALAAAAAAPAA8AQAINhI+py+0Po5y02otnAQA7';
|
||||
$table->add('title', $this->gettext('qrcode'));
|
||||
$table->add('pl-3 pr-3',
|
||||
$table->add(
|
||||
'pl-3 pr-3',
|
||||
html::div('explain form-text', $this->gettext("qrcodeexplain$method"))
|
||||
. html::tag('img', array('src' => $gif, 'class' => 'qrcode mt-2', 'rel' => $method))
|
||||
. html::tag('img', ['src' => $gif, 'class' => 'qrcode mt-2', 'rel' => $method])
|
||||
);
|
||||
|
||||
// add row for testing the factor
|
||||
$field_id = 'rcmk2faverify' . $method;
|
||||
$table->add('title', html::label($field_id, $this->gettext('verifycode')));
|
||||
$table->add(null,
|
||||
html::tag('input', array('type' => 'text', 'name' => '_verify_code', 'id' => $field_id, 'class' => 'k2fa-verify', 'size' => 20, 'required' => true)) .
|
||||
$table->add(
|
||||
null,
|
||||
html::tag('input', ['type' => 'text', 'name' => '_verify_code', 'id' => $field_id, 'class' => 'k2fa-verify', 'size' => 20, 'required' => true]) .
|
||||
html::div('explain form-text', $this->gettext("verifycodeexplain$method"))
|
||||
);
|
||||
}
|
||||
|
||||
$input_id = new html_hiddenfield(array('name' => '_prop[id]', 'value' => ''));
|
||||
$input_id = new html_hiddenfield(['name' => '_prop[id]', 'value' => '']);
|
||||
|
||||
$out .= html::tag('form', array(
|
||||
$out .= html::tag(
|
||||
'form',
|
||||
[
|
||||
'method' => 'post',
|
||||
'action' => '#',
|
||||
'id' => 'kolab2fa-prop-' . $method,
|
||||
'style' => 'display:none',
|
||||
'class' => 'propform',
|
||||
),
|
||||
html::tag('fieldset', array(),
|
||||
html::tag('legend', array(), $this->gettext($method)) .
|
||||
],
|
||||
html::tag(
|
||||
'fieldset',
|
||||
[],
|
||||
html::tag('legend', [], $this->gettext($method)) .
|
||||
html::div('factorprop', $table->show()) .
|
||||
$input_id->show()
|
||||
)
|
||||
|
@ -620,15 +629,16 @@ class kolab_2fa extends rcube_plugin
|
|||
/**
|
||||
* Render the high-security-dialog content
|
||||
*/
|
||||
public function settings_highsecuritydialog($attrib = array())
|
||||
public function settings_highsecuritydialog($attrib = [])
|
||||
{
|
||||
$attrib += array('id' => 'kolab2fa-highsecuritydialog');
|
||||
$attrib += ['id' => 'kolab2fa-highsecuritydialog'];
|
||||
|
||||
$field_id = 'rcmk2facode';
|
||||
$input = new html_inputfield(array('name' => '_code', 'id' => $field_id, 'class' => 'verifycode', 'size' => 20));
|
||||
$label = html::label(array('for' => $field_id, 'class' => 'col-form-label col-sm-4'), '$name');
|
||||
$input = new html_inputfield(['name' => '_code', 'id' => $field_id, 'class' => 'verifycode', 'size' => 20]);
|
||||
$label = html::label(['for' => $field_id, 'class' => 'col-form-label col-sm-4'], '$name');
|
||||
|
||||
return html::div($attrib,
|
||||
return html::div(
|
||||
$attrib,
|
||||
html::div('explain form-text', $this->gettext('highsecuritydialog'))
|
||||
. html::div('propform row form-group', $label . html::div('col-sm-8', $input->show('')))
|
||||
);
|
||||
|
@ -646,30 +656,28 @@ class kolab_2fa extends rcube_plugin
|
|||
$storage = $this->get_storage($rcmail->get_user_name());
|
||||
$success = false;
|
||||
$errors = 0;
|
||||
$save_data = array();
|
||||
$save_data = [];
|
||||
|
||||
if ($driver = $this->get_driver($method)) {
|
||||
if ($data === false) {
|
||||
if ($this->check_secure_mode()) {
|
||||
// remove method from active factors and clear stored settings
|
||||
$success = $driver->clear();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$errors++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// verify the submitted code before saving
|
||||
$verify_code = rcube_utils::get_input_value('_verify_code', rcube_utils::INPUT_POST);
|
||||
$timestamp = intval(rcube_utils::get_input_value('_timestamp', rcube_utils::INPUT_POST));
|
||||
if (!empty($verify_code)) {
|
||||
if (!$driver->verify($verify_code, $timestamp)) {
|
||||
$this->api->output->command('plugin.verify_response', array(
|
||||
$this->api->output->command('plugin.verify_response', [
|
||||
'id' => $driver->id,
|
||||
'method' => $driver->method,
|
||||
'success' => false,
|
||||
'message' => str_replace('$method', $this->gettext($driver->method), $this->gettext('codeverificationfailed'))
|
||||
));
|
||||
'message' => str_replace('$method', $this->gettext($driver->method), $this->gettext('codeverificationfailed')),
|
||||
]);
|
||||
$this->api->output->send();
|
||||
}
|
||||
}
|
||||
|
@ -686,9 +694,8 @@ class kolab_2fa extends rcube_plugin
|
|||
// commit changes to the user properties
|
||||
if (!$errors) {
|
||||
if ($success = $driver->commit()) {
|
||||
$save_data = $data !== false ? $this->format_props($driver->props()) : array();
|
||||
}
|
||||
else {
|
||||
$save_data = $data !== false ? $this->format_props($driver->props()) : [];
|
||||
} else {
|
||||
$errors++;
|
||||
}
|
||||
}
|
||||
|
@ -696,12 +703,11 @@ class kolab_2fa extends rcube_plugin
|
|||
|
||||
if ($success) {
|
||||
$this->api->output->show_message($data === false ? $this->gettext('factorremovesuccess') : $this->gettext('factorsavesuccess'), 'confirmation');
|
||||
$this->api->output->command('plugin.save_success', array(
|
||||
$this->api->output->command('plugin.save_success', [
|
||||
'method' => $method,
|
||||
'active' => $data !== false,
|
||||
'id' => $driver->id) + $save_data);
|
||||
}
|
||||
else if ($errors) {
|
||||
'id' => $driver->id] + $save_data);
|
||||
} elseif ($errors) {
|
||||
$this->api->output->show_message($this->gettext('factorsaveerror'), 'error');
|
||||
$this->api->output->command('plugin.reset_form', $data !== false ? $method : null);
|
||||
}
|
||||
|
@ -717,7 +723,7 @@ class kolab_2fa extends rcube_plugin
|
|||
$method = rcube_utils::get_input_value('_method', rcube_utils::INPUT_POST);
|
||||
|
||||
if ($driver = $this->get_driver($method)) {
|
||||
$data = array('method' => $method, 'id' => $driver->id);
|
||||
$data = ['method' => $method, 'id' => $driver->id];
|
||||
|
||||
foreach ($driver->props(true) as $field => $prop) {
|
||||
$data[$field] = $prop['text'] ?: $prop['value'];
|
||||
|
@ -733,11 +739,10 @@ class kolab_2fa extends rcube_plugin
|
|||
->setSize(240)
|
||||
->setPadding(10)
|
||||
->setErrorCorrection('high')
|
||||
->setForegroundColor(array('r' => 0, 'g' => 0, 'b' => 0, 'a' => 0))
|
||||
->setBackgroundColor(array('r' => 255, 'g' => 255, 'b' => 255, 'a' => 0));
|
||||
->setForegroundColor(['r' => 0, 'g' => 0, 'b' => 0, 'a' => 0])
|
||||
->setBackgroundColor(['r' => 255, 'g' => 255, 'b' => 255, 'a' => 0]);
|
||||
$data['qrcode'] = base64_encode($qr->get());
|
||||
}
|
||||
catch (Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
rcube::raise_error($e, true, false);
|
||||
}
|
||||
}
|
||||
|
@ -776,12 +781,15 @@ class kolab_2fa extends rcube_plugin
|
|||
$_SESSION['kolab_2fa_secure_mode'] = time();
|
||||
}
|
||||
|
||||
$this->api->output->command('plugin.verify_response', array(
|
||||
$this->api->output->command('plugin.verify_response', [
|
||||
'method' => $method,
|
||||
'success' => $success,
|
||||
'message' => str_replace('$method', $this->gettext($method),
|
||||
$this->gettext($success ? 'codeverificationpassed' : 'codeverificationfailed'))
|
||||
));
|
||||
'message' => str_replace(
|
||||
'$method',
|
||||
$this->gettext($method),
|
||||
$this->gettext($success ? 'codeverificationpassed' : 'codeverificationfailed')
|
||||
),
|
||||
]);
|
||||
|
||||
$this->api->output->send();
|
||||
}
|
||||
|
@ -792,7 +800,7 @@ class kolab_2fa extends rcube_plugin
|
|||
protected function format_props($props)
|
||||
{
|
||||
$rcmail = rcmail::get_instance();
|
||||
$values = array();
|
||||
$values = [];
|
||||
|
||||
foreach ($props as $key => $prop) {
|
||||
switch ($prop['type']) {
|
||||
|
|
|
@ -29,47 +29,47 @@ abstract class Base
|
|||
public $id;
|
||||
public $storage;
|
||||
|
||||
protected $config = array();
|
||||
protected $props = array();
|
||||
protected $user_props = array();
|
||||
protected $config = [];
|
||||
protected $props = [];
|
||||
protected $user_props = [];
|
||||
protected $pending_changes = false;
|
||||
protected $temporary = false;
|
||||
protected $allowed_props = array('username');
|
||||
protected $allowed_props = ['username'];
|
||||
|
||||
public $user_settings = array(
|
||||
'active' => array(
|
||||
public $user_settings = [
|
||||
'active' => [
|
||||
'type' => 'boolean',
|
||||
'editable' => false,
|
||||
'hidden' => false,
|
||||
'default' => false,
|
||||
),
|
||||
'label' => array(
|
||||
],
|
||||
'label' => [
|
||||
'type' => 'text',
|
||||
'editable' => true,
|
||||
'label' => 'label',
|
||||
'generator' => 'default_label',
|
||||
),
|
||||
'created' => array(
|
||||
],
|
||||
'created' => [
|
||||
'type' => 'datetime',
|
||||
'editable' => false,
|
||||
'hidden' => false,
|
||||
'label' => 'created',
|
||||
'generator' => 'time',
|
||||
),
|
||||
);
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* Static factory method
|
||||
*/
|
||||
public static function factory($id, $config)
|
||||
{
|
||||
list($method) = explode(':', $id);
|
||||
[$method] = explode(':', $id);
|
||||
|
||||
$classmap = array(
|
||||
$classmap = [
|
||||
'totp' => '\\Kolab2FA\\Driver\\TOTP',
|
||||
'hotp' => '\\Kolab2FA\\Driver\\HOTP',
|
||||
'yubikey' => '\\Kolab2FA\\Driver\\Yubikey',
|
||||
);
|
||||
];
|
||||
|
||||
$cls = $classmap[strtolower($method)];
|
||||
if ($cls && class_exists($cls)) {
|
||||
|
@ -88,8 +88,7 @@ abstract class Base
|
|||
|
||||
if (!empty($id) && $id != $this->method) {
|
||||
$this->id = $id;
|
||||
}
|
||||
else { // generate random ID
|
||||
} else { // generate random ID
|
||||
$this->id = $this->method . ':' . bin2hex(openssl_random_pseudo_bytes(12));
|
||||
$this->temporary = true;
|
||||
}
|
||||
|
@ -117,27 +116,27 @@ abstract class Base
|
|||
*
|
||||
* @return bool True if valid, false otherwise
|
||||
*/
|
||||
abstract function verify($code, $timestamp = null);
|
||||
abstract public function verify($code, $timestamp = null);
|
||||
|
||||
/**
|
||||
* Getter for user-visible properties
|
||||
*/
|
||||
public function props($force = false)
|
||||
{
|
||||
$data = array();
|
||||
$data = [];
|
||||
|
||||
foreach ($this->user_settings as $key => $p) {
|
||||
if (!empty($p['private'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$data[$key] = array(
|
||||
$data[$key] = [
|
||||
'type' => $p['type'],
|
||||
'editable' => $p['editable'] ?? false,
|
||||
'hidden' => $p['hidden'] ?? false,
|
||||
'label' => $p['label'] ?? '',
|
||||
'value' => $this->get($key, $force),
|
||||
);
|
||||
];
|
||||
|
||||
// format value into text
|
||||
switch ($p['type']) {
|
||||
|
@ -152,6 +151,7 @@ abstract class Base
|
|||
break;
|
||||
}
|
||||
|
||||
// no break
|
||||
default:
|
||||
$data[$key]['text'] = $data[$key]['value'];
|
||||
}
|
||||
|
@ -171,12 +171,12 @@ abstract class Base
|
|||
public function generate_secret($length = 16)
|
||||
{
|
||||
// Base32 characters
|
||||
$chars = array(
|
||||
$chars = [
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', // 7
|
||||
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 15
|
||||
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 23
|
||||
'Y', 'Z', '2', '3', '4', '5', '6', '7', // 31
|
||||
);
|
||||
];
|
||||
|
||||
$secret = '';
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
|
@ -211,7 +211,7 @@ abstract class Base
|
|||
if (!isset($value) && $force && !empty($this->user_settings[$key]['generator'])) {
|
||||
$func = $this->user_settings[$key]['generator'];
|
||||
if (is_string($func) && !is_callable($func)) {
|
||||
$func = array($this, $func);
|
||||
$func = [$this, $func];
|
||||
}
|
||||
if (is_callable($func)) {
|
||||
$value = call_user_func($func);
|
||||
|
@ -220,8 +220,7 @@ abstract class Base
|
|||
$this->set_user_prop($key, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$value = $this->props[$key] ?? null;
|
||||
}
|
||||
|
||||
|
@ -243,9 +242,8 @@ abstract class Base
|
|||
|
||||
$setter = 'set_' . $key;
|
||||
if (method_exists($this, $setter)) {
|
||||
call_user_func(array($this, $setter), $value);
|
||||
}
|
||||
else if (in_array($key, $this->allowed_props)) {
|
||||
call_user_func([$this, $setter], $value);
|
||||
} elseif (in_array($key, $this->allowed_props)) {
|
||||
$this->props[$key] = $value;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,5 +4,4 @@ namespace Kolab2FA\Driver;
|
|||
|
||||
class Exception extends \Exception
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
@ -27,11 +27,11 @@ class HOTP extends Base
|
|||
{
|
||||
public $method = 'hotp';
|
||||
|
||||
protected $config = array(
|
||||
protected $config = [
|
||||
'digits' => 6,
|
||||
'window' => 4,
|
||||
'digest' => 'sha1',
|
||||
);
|
||||
];
|
||||
|
||||
protected $backend;
|
||||
|
||||
|
@ -42,22 +42,22 @@ class HOTP extends Base
|
|||
{
|
||||
parent::init($config);
|
||||
|
||||
$this->user_settings += array(
|
||||
'secret' => array(
|
||||
$this->user_settings += [
|
||||
'secret' => [
|
||||
'type' => 'text',
|
||||
'private' => true,
|
||||
'label' => 'secret',
|
||||
'generator' => 'generate_secret',
|
||||
),
|
||||
'counter' => array(
|
||||
],
|
||||
'counter' => [
|
||||
'type' => 'integer',
|
||||
'editable' => false,
|
||||
'hidden' => true,
|
||||
'generator' => 'random_counter',
|
||||
),
|
||||
);
|
||||
],
|
||||
];
|
||||
|
||||
if (!in_array($this->config['digest'], array('md5', 'sha1', 'sha256', 'sha512'))) {
|
||||
if (!in_array($this->config['digest'], ['md5', 'sha1', 'sha256', 'sha512'])) {
|
||||
throw new \Exception("'{$this->config['digest']}' digest is not supported.");
|
||||
}
|
||||
|
||||
|
@ -106,8 +106,7 @@ class HOTP extends Base
|
|||
// store incremented counter value
|
||||
$this->set('counter', $this->backend->getCounter());
|
||||
$this->commit();
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
} catch (\Exception $e) {
|
||||
// LOG: exception
|
||||
// rcube::console("VERIFY HOTP: $this->id, " . strval($e));
|
||||
$pass = false;
|
||||
|
|
|
@ -27,11 +27,11 @@ class TOTP extends Base
|
|||
{
|
||||
public $method = 'totp';
|
||||
|
||||
protected $config = array(
|
||||
protected $config = [
|
||||
'digits' => 6,
|
||||
'interval' => 30,
|
||||
'digest' => 'sha1',
|
||||
);
|
||||
];
|
||||
|
||||
protected $backend;
|
||||
|
||||
|
@ -42,16 +42,16 @@ class TOTP extends Base
|
|||
{
|
||||
parent::init($config);
|
||||
|
||||
$this->user_settings += array(
|
||||
'secret' => array(
|
||||
$this->user_settings += [
|
||||
'secret' => [
|
||||
'type' => 'text',
|
||||
'private' => true,
|
||||
'label' => 'secret',
|
||||
'generator' => 'generate_secret',
|
||||
),
|
||||
);
|
||||
],
|
||||
];
|
||||
|
||||
if (!in_array($this->config['digest'], array('md5', 'sha1', 'sha256', 'sha512'))) {
|
||||
if (!in_array($this->config['digest'], ['md5', 'sha1', 'sha256', 'sha512'])) {
|
||||
throw new \Exception("'{$this->config['digest']}' digest is not supported.");
|
||||
}
|
||||
|
||||
|
|
|
@ -36,13 +36,13 @@ class Yubikey extends Base
|
|||
{
|
||||
parent::init($config);
|
||||
|
||||
$this->user_settings += array(
|
||||
'yubikeyid' => array(
|
||||
$this->user_settings += [
|
||||
'yubikeyid' => [
|
||||
'type' => 'text',
|
||||
'editable' => true,
|
||||
'label' => 'secret',
|
||||
),
|
||||
);
|
||||
],
|
||||
];
|
||||
|
||||
// initialize validator
|
||||
$this->backend = new \Yubikey\Validate($this->config['apikey'], $this->config['clientid']);
|
||||
|
@ -76,8 +76,7 @@ class Yubikey extends Base
|
|||
try {
|
||||
$response = $this->backend->check($code);
|
||||
$pass = $response->success() === true;
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
} catch (\Exception $e) {
|
||||
// TODO: log exception
|
||||
}
|
||||
}
|
||||
|
@ -99,8 +98,7 @@ class Yubikey extends Base
|
|||
// TODO: report error
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
} catch (\Exception $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
namespace Kolab2FA\Log;
|
||||
|
||||
use \rcube;
|
||||
use rcube;
|
||||
|
||||
class RcubeLogger implements Logger
|
||||
{
|
||||
|
@ -55,26 +55,25 @@ class RcubeLogger implements Logger
|
|||
}
|
||||
|
||||
switch ($level) {
|
||||
case LOG_DEBUG:
|
||||
case LOG_INFO:
|
||||
case LOG_NOTICE:
|
||||
if ($level >= $this->level) {
|
||||
rcube::write_log($this->name ?: 'console', $message);
|
||||
}
|
||||
break;
|
||||
case LOG_DEBUG:
|
||||
case LOG_INFO:
|
||||
case LOG_NOTICE:
|
||||
if ($level >= $this->level) {
|
||||
rcube::write_log($this->name ?: 'console', $message);
|
||||
}
|
||||
break;
|
||||
|
||||
case LOG_EMERG:
|
||||
case LOG_ALERT:
|
||||
case LOG_CRIT:
|
||||
case LOG_ERR:
|
||||
case LOG_WARNING:
|
||||
rcube::raise_error(array(
|
||||
'code' => 600,
|
||||
'type' => 'php',
|
||||
'message' => $message,
|
||||
), true, false);
|
||||
break;
|
||||
case LOG_EMERG:
|
||||
case LOG_ALERT:
|
||||
case LOG_CRIT:
|
||||
case LOG_ERR:
|
||||
case LOG_WARNING:
|
||||
rcube::raise_error([
|
||||
'code' => 600,
|
||||
'type' => 'php',
|
||||
'message' => $message,
|
||||
], true, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
namespace Kolab2FA\Log;
|
||||
|
||||
use \rcube;
|
||||
use rcube;
|
||||
|
||||
class Syslog implements Logger
|
||||
{
|
||||
|
|
|
@ -23,13 +23,12 @@
|
|||
|
||||
namespace Kolab2FA\Storage;
|
||||
|
||||
use \Kolab2FA\Log;
|
||||
|
||||
use Kolab2FA\Log;
|
||||
|
||||
abstract class Base
|
||||
{
|
||||
public $username = null;
|
||||
protected $config = array();
|
||||
protected $config = [];
|
||||
protected $logger;
|
||||
|
||||
/**
|
||||
|
@ -37,11 +36,11 @@ abstract class Base
|
|||
*/
|
||||
public static function factory($backend, $config)
|
||||
{
|
||||
$classmap = array(
|
||||
$classmap = [
|
||||
'ldap' => '\\Kolab2FA\\Storage\\LDAP',
|
||||
'roundcube' => '\\Kolab2FA\\Storage\\RcubeUser',
|
||||
'rcubeuser' => '\\Kolab2FA\\Storage\\RcubeUser',
|
||||
);
|
||||
];
|
||||
|
||||
$cls = $classmap[strtolower($backend)];
|
||||
if ($cls && class_exists($cls)) {
|
||||
|
@ -73,7 +72,7 @@ abstract class Base
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
public function set_logger(Log\Logger $logger)
|
||||
{
|
||||
|
@ -81,8 +80,7 @@ abstract class Base
|
|||
|
||||
if (!empty($this->config['debug'])) {
|
||||
$this->logger->set_level(LOG_DEBUG);
|
||||
}
|
||||
else if (!empty($this->config['loglevel'])) {
|
||||
} elseif (!empty($this->config['loglevel'])) {
|
||||
$this->logger->set_level($this->config['loglevel']);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,5 +4,4 @@ namespace Kolab2FA\Storage;
|
|||
|
||||
class Exception extends \Exception
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
@ -23,15 +23,15 @@
|
|||
|
||||
namespace Kolab2FA\Storage;
|
||||
|
||||
use \Net_LDAP3;
|
||||
use \Kolab2FA\Log\Logger;
|
||||
use Net_LDAP3;
|
||||
use Kolab2FA\Log\Logger;
|
||||
|
||||
class LDAP extends Base
|
||||
{
|
||||
public $userdn;
|
||||
|
||||
private $cache = array();
|
||||
private $ldapcache = array();
|
||||
private $cache = [];
|
||||
private $ldapcache = [];
|
||||
private $conn;
|
||||
private $error;
|
||||
private $ready = false;
|
||||
|
@ -42,7 +42,7 @@ class LDAP extends Base
|
|||
parent::init($config);
|
||||
|
||||
$this->conn = new Net_LDAP3($config);
|
||||
$this->conn->config_set('log_hook', array($this, 'log'));
|
||||
$this->conn->config_set('log_hook', [$this, 'log']);
|
||||
|
||||
$this->conn->connect();
|
||||
|
||||
|
@ -62,12 +62,12 @@ class LDAP extends Base
|
|||
*/
|
||||
public function enumerate($active = true)
|
||||
{
|
||||
$filter = $this->parse_vars($this->config['filter'], '*');
|
||||
$filter = $this->parse_vars($this->config['filter'], '*');
|
||||
$base_dn = $this->parse_vars($this->config['base_dn'], '*');
|
||||
$scope = $this->config['scope'] ?: 'sub';
|
||||
$ids = array();
|
||||
$ids = [];
|
||||
|
||||
if ($this->ready && ($result = $this->conn->search($base_dn, $filter, $scope, array($this->config['fieldmap']['id'], $this->config['fieldmap']['active'])))) {
|
||||
if ($this->ready && ($result = $this->conn->search($base_dn, $filter, $scope, [$this->config['fieldmap']['id'], $this->config['fieldmap']['active']]))) {
|
||||
foreach ($result as $dn => $entry) {
|
||||
$rec = $this->field_mapping($dn, Net_LDAP3::normalize_entry($entry, true));
|
||||
if (!empty($rec['id']) && ($active === null || $active == $rec['active'])) {
|
||||
|
@ -99,19 +99,18 @@ class LDAP extends Base
|
|||
public function write($key, $value)
|
||||
{
|
||||
$success = false;
|
||||
$ldap_attrs = array();
|
||||
$ldap_attrs = [];
|
||||
|
||||
if (is_array($value)) {
|
||||
// add some default values
|
||||
$value += (array)$this->config['defaults'] + array('active' => false, 'username' => $this->username, 'userdn' => $this->userdn);
|
||||
$value += (array)$this->config['defaults'] + ['active' => false, 'username' => $this->username, 'userdn' => $this->userdn];
|
||||
|
||||
foreach ($value as $k => $val) {
|
||||
if ($attr = $this->config['fieldmap'][$k]) {
|
||||
$ldap_attrs[$attr] = $this->value_mapping($k, $val, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// invalid data structure
|
||||
return false;
|
||||
}
|
||||
|
@ -125,12 +124,12 @@ class LDAP extends Base
|
|||
$success = !empty($result);
|
||||
}
|
||||
// insert new record
|
||||
else if ($this->ready) {
|
||||
elseif ($this->ready) {
|
||||
$entry_dn = $this->get_entry_dn($this->username, $key);
|
||||
|
||||
// add object class attribute
|
||||
$me = $this;
|
||||
$ldap_attrs['objectclass'] = array_map(function($cls) use ($me, $key) {
|
||||
$ldap_attrs['objectclass'] = array_map(function ($cls) use ($me, $key) {
|
||||
return $me->parse_vars($cls, $key);
|
||||
}, (array)$this->config['objectclass']);
|
||||
|
||||
|
@ -139,7 +138,7 @@ class LDAP extends Base
|
|||
|
||||
if ($success) {
|
||||
$this->cache[$key] = $value;
|
||||
$this->ldapcache = array();
|
||||
$this->ldapcache = [];
|
||||
|
||||
// cleanup: remove disabled/inactive/temporary entries
|
||||
if ($value['active']) {
|
||||
|
@ -185,8 +184,8 @@ class LDAP extends Base
|
|||
parent::set_username($username);
|
||||
|
||||
// reset cached values
|
||||
$this->cache = array();
|
||||
$this->ldapcache = array();
|
||||
$this->cache = [];
|
||||
$this->ldapcache = [];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -198,7 +197,7 @@ class LDAP extends Base
|
|||
return false;
|
||||
}
|
||||
|
||||
$auth_roles = array();
|
||||
$auth_roles = [];
|
||||
foreach ($this->enumerate(true) as $id) {
|
||||
foreach ($this->config['user_roles'] as $prefix => $role) {
|
||||
if (strpos($id, $prefix) === 0) {
|
||||
|
@ -208,12 +207,12 @@ class LDAP extends Base
|
|||
}
|
||||
|
||||
$role_attr = $this->config['fieldmap']['roles'] ?: 'nsroledn';
|
||||
if ($user_attrs = $this->conn->get_entry($this->userdn, array($role_attr))) {
|
||||
if ($user_attrs = $this->conn->get_entry($this->userdn, [$role_attr])) {
|
||||
$internals = array_values($this->config['user_roles']);
|
||||
$new_attrs = $old_attrs = Net_LDAP3::normalize_entry($user_attrs);
|
||||
$new_attrs[$role_attr] = array_merge(
|
||||
array_unique($auth_roles),
|
||||
array_filter((array)$old_attrs[$role_attr], function($f) use ($internals) { return !in_array($f, $internals); })
|
||||
array_filter((array)$old_attrs[$role_attr], function ($f) use ($internals) { return !in_array($f, $internals); })
|
||||
);
|
||||
|
||||
$result = $this->conn->modify_entry($this->userdn, $old_attrs, $new_attrs);
|
||||
|
@ -231,7 +230,7 @@ class LDAP extends Base
|
|||
$entry_dn = $this->get_entry_dn($user, $key);
|
||||
|
||||
if (!isset($this->ldapcache[$entry_dn])) {
|
||||
$this->ldapcache[$entry_dn] = array();
|
||||
$this->ldapcache[$entry_dn] = [];
|
||||
|
||||
if ($this->ready && ($entry = $this->conn->get_entry($entry_dn, array_values($this->config['fieldmap'])))) {
|
||||
$this->ldapcache[$entry_dn] = $this->field_mapping($entry_dn, Net_LDAP3::normalize_entry($entry, true));
|
||||
|
@ -263,8 +262,7 @@ class LDAP extends Base
|
|||
$attr_lc = strtolower($attr);
|
||||
if (isset($entry[$attr_lc])) {
|
||||
$entry[$field] = $this->value_mapping($field, $entry[$attr_lc], true);
|
||||
}
|
||||
else if (isset($entry[$attr])) {
|
||||
} elseif (isset($entry[$attr])) {
|
||||
$entry[$field] = $this->value_mapping($field, $entry[$attr], true);
|
||||
}
|
||||
}
|
||||
|
@ -283,11 +281,10 @@ class LDAP extends Base
|
|||
}
|
||||
|
||||
if (is_array($value)) {
|
||||
$value = array_filter(array_map(function($val) use ($map) {
|
||||
$value = array_filter(array_map(function ($val) use ($map) {
|
||||
return $map[$val];
|
||||
}, $value));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$value = $map[$value];
|
||||
}
|
||||
}
|
||||
|
@ -317,9 +314,8 @@ class LDAP extends Base
|
|||
$user = $this->username;
|
||||
|
||||
if (strpos($user, '@') > 0) {
|
||||
list($u, $d) = explode('@', $user);
|
||||
}
|
||||
else if ($this->userdn) {
|
||||
[$u, $d] = explode('@', $user);
|
||||
} elseif ($this->userdn) {
|
||||
$u = $this->userdn;
|
||||
$d = trim(str_replace(',dc=', '.', substr($u, strpos($u, ',dc='))), '.');
|
||||
}
|
||||
|
@ -343,7 +339,7 @@ class LDAP extends Base
|
|||
}
|
||||
}
|
||||
|
||||
$replaces = array('%dc' => $dc, '%d' => $d ?? '', '%fu' => $user, '%u' => $u ?? '', '%c' => $class);
|
||||
$replaces = ['%dc' => $dc, '%d' => $d ?? '', '%fu' => $user, '%u' => $u ?? '', '%c' => $class];
|
||||
|
||||
return strtr($str, $replaces);
|
||||
}
|
||||
|
|
|
@ -23,17 +23,17 @@
|
|||
|
||||
namespace Kolab2FA\Storage;
|
||||
|
||||
use \rcmail;
|
||||
use \rcube_user;
|
||||
use rcmail;
|
||||
use rcube_user;
|
||||
|
||||
class RcubeUser extends Base
|
||||
{
|
||||
// sefault config
|
||||
protected $config = array(
|
||||
'keymap' => array(),
|
||||
);
|
||||
protected $config = [
|
||||
'keymap' => [],
|
||||
];
|
||||
|
||||
private $cache = array();
|
||||
private $cache = [];
|
||||
private $user;
|
||||
|
||||
public function init(array $config)
|
||||
|
@ -50,12 +50,12 @@ class RcubeUser extends Base
|
|||
public function enumerate()
|
||||
{
|
||||
if ($factors = $this->get_factors()) {
|
||||
return array_keys(array_filter($factors, function($prop) {
|
||||
return array_keys(array_filter($factors, function ($prop) {
|
||||
return !empty($prop['active']);
|
||||
}));
|
||||
}
|
||||
|
||||
return array();
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -86,7 +86,7 @@ class RcubeUser extends Base
|
|||
$factors[$key] = $value;
|
||||
|
||||
$pkey = $this->key2property('blob');
|
||||
$save_data = array($pkey => $factors);
|
||||
$save_data = [$pkey => $factors];
|
||||
$update_index = false;
|
||||
|
||||
// remove entry
|
||||
|
@ -95,8 +95,8 @@ class RcubeUser extends Base
|
|||
$update_index = true;
|
||||
}
|
||||
// remove non-active entries
|
||||
else if (!empty($value['active'])) {
|
||||
$factors = array_filter($factors, function($prop) {
|
||||
elseif (!empty($value['active'])) {
|
||||
$factors = array_filter($factors, function ($prop) {
|
||||
return !empty($prop['active']);
|
||||
});
|
||||
$update_index = true;
|
||||
|
@ -105,7 +105,7 @@ class RcubeUser extends Base
|
|||
// update the index of active factors
|
||||
if ($update_index) {
|
||||
$save_data[$this->key2property('factors')] = array_keys(
|
||||
array_filter($factors, function($prop) {
|
||||
array_filter($factors, function ($prop) {
|
||||
return !empty($prop['active']);
|
||||
})
|
||||
);
|
||||
|
@ -139,7 +139,7 @@ class RcubeUser extends Base
|
|||
parent::set_username($username);
|
||||
|
||||
// reset cached values
|
||||
$this->cache = array();
|
||||
$this->cache = [];
|
||||
$this->user = null;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,4 +4,4 @@
|
|||
$config['activesync_setup_url'] = 'https://kb.kolabenterprise.com/documentation/setting-up-an-activesync-client';
|
||||
// Force a subscription state per devicetype (lowercase) and folder
|
||||
// States can be: 0 => not subscribed, 1 => subscribed, 2 => subscribed with alarm
|
||||
$config['activesync_force_subscriptions'] = array('windowsoutlook15' => array('INBOX' => 1, 'Sent' => 1, 'Trash' => 1, 'Calendar' => 1, 'Contacts' => 1, 'Tasks' => 1));
|
||||
$config['activesync_force_subscriptions'] = ['windowsoutlook15' => ['INBOX' => 1, 'Sent' => 1, 'Trash' => 1, 'Calendar' => 1, 'Contacts' => 1, 'Tasks' => 1]];
|
||||
|
|
|
@ -34,8 +34,8 @@ class kolab_activesync extends rcube_plugin
|
|||
private $folder_meta;
|
||||
private $root_meta;
|
||||
|
||||
const ROOT_MAILBOX = 'INBOX';
|
||||
const ASYNC_KEY = '/private/vendor/kolab/activesync';
|
||||
public const ROOT_MAILBOX = 'INBOX';
|
||||
public const ASYNC_KEY = '/private/vendor/kolab/activesync';
|
||||
|
||||
|
||||
/**
|
||||
|
@ -47,12 +47,12 @@ class kolab_activesync extends rcube_plugin
|
|||
|
||||
$this->require_plugin('libkolab');
|
||||
|
||||
$this->register_action('plugin.activesync', array($this, 'config_view'));
|
||||
$this->register_action('plugin.activesync-config', array($this, 'config_frame'));
|
||||
$this->register_action('plugin.activesync-json', array($this, 'json_command'));
|
||||
$this->register_action('plugin.activesync', [$this, 'config_view']);
|
||||
$this->register_action('plugin.activesync-config', [$this, 'config_frame']);
|
||||
$this->register_action('plugin.activesync-json', [$this, 'json_command']);
|
||||
|
||||
$this->add_hook('settings_actions', array($this, 'settings_actions'));
|
||||
$this->add_hook('folder_form', array($this, 'folder_form'));
|
||||
$this->add_hook('settings_actions', [$this, 'settings_actions']);
|
||||
$this->add_hook('folder_form', [$this, 'folder_form']);
|
||||
|
||||
$this->add_texts('localization/');
|
||||
|
||||
|
@ -65,15 +65,15 @@ class kolab_activesync extends rcube_plugin
|
|||
/**
|
||||
* Adds Activesync section in Settings
|
||||
*/
|
||||
function settings_actions($args)
|
||||
public function settings_actions($args)
|
||||
{
|
||||
$args['actions'][] = array(
|
||||
$args['actions'][] = [
|
||||
'action' => 'plugin.activesync',
|
||||
'class' => 'activesync',
|
||||
'label' => 'tabtitle',
|
||||
'domain' => 'kolab_activesync',
|
||||
'title' => 'activesynctitle',
|
||||
);
|
||||
];
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ class kolab_activesync extends rcube_plugin
|
|||
* Handler for folder info/edit form (folder_form hook).
|
||||
* Adds ActiveSync section.
|
||||
*/
|
||||
function folder_form($args)
|
||||
public function folder_form($args)
|
||||
{
|
||||
$mbox_imap = $args['options']['name'] ?? '';
|
||||
|
||||
|
@ -98,8 +98,8 @@ class kolab_activesync extends rcube_plugin
|
|||
return $args;
|
||||
}
|
||||
|
||||
list($type, ) = explode('.', (string) kolab_storage::folder_type($mbox_imap));
|
||||
if ($type && !in_array($type, array('mail', 'event', 'contact', 'task', 'note'))) {
|
||||
[$type, ] = explode('.', (string) kolab_storage::folder_type($mbox_imap));
|
||||
if ($type && !in_array($type, ['mail', 'event', 'contact', 'task', 'note'])) {
|
||||
return $args;
|
||||
}
|
||||
|
||||
|
@ -107,10 +107,10 @@ class kolab_activesync extends rcube_plugin
|
|||
$this->ui = new kolab_activesync_ui($this);
|
||||
|
||||
if ($content = $this->ui->folder_options_table($mbox_imap, $devices, $type)) {
|
||||
$args['form']['activesync'] = array(
|
||||
$args['form']['activesync'] = [
|
||||
'name' => $this->gettext('tabtitle'),
|
||||
'content' => $content,
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
return $args;
|
||||
|
@ -125,68 +125,70 @@ class kolab_activesync extends rcube_plugin
|
|||
$imei = rcube_utils::get_input_value('id', rcube_utils::INPUT_POST);
|
||||
|
||||
switch ($cmd) {
|
||||
case 'save':
|
||||
$devices = $this->list_devices();
|
||||
$device = $devices[$imei];
|
||||
$subscriptions = (array) rcube_utils::get_input_value('subscribed', rcube_utils::INPUT_POST);
|
||||
$devicealias = rcube_utils::get_input_value('devicealias', rcube_utils::INPUT_POST, true);
|
||||
$device['ALIAS'] = $devicealias;
|
||||
case 'save':
|
||||
$devices = $this->list_devices();
|
||||
$device = $devices[$imei];
|
||||
$subscriptions = (array) rcube_utils::get_input_value('subscribed', rcube_utils::INPUT_POST);
|
||||
$devicealias = rcube_utils::get_input_value('devicealias', rcube_utils::INPUT_POST, true);
|
||||
$device['ALIAS'] = $devicealias;
|
||||
|
||||
$err = !$this->device_update($device, $imei);
|
||||
$err = !$this->device_update($device, $imei);
|
||||
|
||||
if (!$err) {
|
||||
// iterate over folders list and update metadata if necessary
|
||||
// old subscriptions
|
||||
foreach (array_keys($this->folder_meta()) as $folder) {
|
||||
$err |= !$this->folder_set($folder, $imei, intval($subscriptions[$folder]));
|
||||
unset($subscriptions[$folder]);
|
||||
}
|
||||
// new subscription
|
||||
foreach ($subscriptions as $folder => $flag) {
|
||||
$err |= !$this->folder_set($folder, $imei, intval($flag));
|
||||
if (!$err) {
|
||||
// iterate over folders list and update metadata if necessary
|
||||
// old subscriptions
|
||||
foreach (array_keys($this->folder_meta()) as $folder) {
|
||||
$err |= !$this->folder_set($folder, $imei, intval($subscriptions[$folder]));
|
||||
unset($subscriptions[$folder]);
|
||||
}
|
||||
// new subscription
|
||||
foreach ($subscriptions as $folder => $flag) {
|
||||
$err |= !$this->folder_set($folder, $imei, intval($flag));
|
||||
}
|
||||
|
||||
$this->rc->output->command('plugin.activesync_save_complete', [
|
||||
'success' => !$err, 'id' => $imei, 'alias' => rcube::Q($devicealias)]);
|
||||
}
|
||||
|
||||
$this->rc->output->command('plugin.activesync_save_complete', array(
|
||||
'success' => !$err, 'id' => $imei, 'alias' => rcube::Q($devicealias)));
|
||||
}
|
||||
if ($err) {
|
||||
$this->rc->output->show_message($this->gettext('savingerror'), 'error');
|
||||
} else {
|
||||
$this->rc->output->show_message($this->gettext('successfullysaved'), 'confirmation');
|
||||
}
|
||||
|
||||
if ($err)
|
||||
$this->rc->output->show_message($this->gettext('savingerror'), 'error');
|
||||
else
|
||||
$this->rc->output->show_message($this->gettext('successfullysaved'), 'confirmation');
|
||||
break;
|
||||
|
||||
break;
|
||||
case 'delete':
|
||||
foreach ((array) $imei as $id) {
|
||||
$success = $this->device_delete($id);
|
||||
}
|
||||
|
||||
case 'delete':
|
||||
foreach ((array) $imei as $id) {
|
||||
$success = $this->device_delete($id);
|
||||
}
|
||||
if (!empty($success)) {
|
||||
$this->rc->output->show_message($this->gettext('successfullydeleted'), 'confirmation');
|
||||
$this->rc->output->command('plugin.activesync_save_complete', [
|
||||
'success' => true,
|
||||
'delete' => true,
|
||||
'id' => count($imei) > 1 ? 'ALL' : $imei[0],
|
||||
]);
|
||||
} else {
|
||||
$this->rc->output->show_message($this->gettext('savingerror'), 'error');
|
||||
}
|
||||
|
||||
if (!empty($success)) {
|
||||
$this->rc->output->show_message($this->gettext('successfullydeleted'), 'confirmation');
|
||||
$this->rc->output->command('plugin.activesync_save_complete', array(
|
||||
'success' => true,
|
||||
'delete' => true,
|
||||
'id' => count($imei) > 1 ? 'ALL' : $imei[0],
|
||||
));
|
||||
}
|
||||
else
|
||||
$this->rc->output->show_message($this->gettext('savingerror'), 'error');
|
||||
break;
|
||||
|
||||
break;
|
||||
case 'update':
|
||||
$subscription = (int) rcube_utils::get_input_value('flag', rcube_utils::INPUT_POST);
|
||||
$folder = rcube_utils::get_input_value('folder', rcube_utils::INPUT_POST);
|
||||
|
||||
case 'update':
|
||||
$subscription = (int) rcube_utils::get_input_value('flag', rcube_utils::INPUT_POST);
|
||||
$folder = rcube_utils::get_input_value('folder', rcube_utils::INPUT_POST);
|
||||
$err = !$this->folder_set($folder, $imei, $subscription);
|
||||
|
||||
$err = !$this->folder_set($folder, $imei, $subscription);
|
||||
if ($err) {
|
||||
$this->rc->output->show_message($this->gettext('savingerror'), 'error');
|
||||
} else {
|
||||
$this->rc->output->show_message($this->gettext('successfullysaved'), 'confirmation');
|
||||
}
|
||||
|
||||
if ($err)
|
||||
$this->rc->output->show_message($this->gettext('savingerror'), 'error');
|
||||
else
|
||||
$this->rc->output->show_message($this->gettext('successfullysaved'), 'confirmation');
|
||||
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
$this->rc->output->send();
|
||||
|
@ -208,7 +210,7 @@ class kolab_activesync extends rcube_plugin
|
|||
|
||||
$this->ui = new kolab_activesync_ui($this);
|
||||
|
||||
$this->register_handler('plugin.devicelist', array($this->ui, 'device_list'));
|
||||
$this->register_handler('plugin.devicelist', [$this->ui, 'device_list']);
|
||||
|
||||
$this->rc->output->send('kolab_activesync.config');
|
||||
}
|
||||
|
@ -233,8 +235,8 @@ class kolab_activesync extends rcube_plugin
|
|||
return $this->ui->init_message();
|
||||
}
|
||||
|
||||
$this->register_handler('plugin.deviceconfigform', array($this->ui, 'device_config_form'));
|
||||
$this->register_handler('plugin.foldersubscriptions', array($this->ui, 'folder_subscriptions'));
|
||||
$this->register_handler('plugin.deviceconfigform', [$this->ui, 'device_config_form']);
|
||||
$this->register_handler('plugin.foldersubscriptions', [$this->ui, 'folder_subscriptions']);
|
||||
|
||||
$imei = rcube_utils::get_input_value('_id', rcube_utils::INPUT_GPC);
|
||||
$devices = $this->list_devices();
|
||||
|
@ -243,9 +245,8 @@ class kolab_activesync extends rcube_plugin
|
|||
$this->ui->device = $device;
|
||||
$this->ui->device['_id'] = $imei;
|
||||
$this->rc->output->set_env('active_device', $imei);
|
||||
$this->rc->output->command('parent.enable_command','plugin.delete-device', true);
|
||||
}
|
||||
else {
|
||||
$this->rc->output->command('parent.enable_command', 'plugin.delete-device', true);
|
||||
} else {
|
||||
$this->rc->output->show_message($this->gettext('devicenotfound'), 'error');
|
||||
}
|
||||
|
||||
|
@ -276,9 +277,8 @@ class kolab_activesync extends rcube_plugin
|
|||
// @TODO: consider server annotation instead of INBOX
|
||||
if ($meta = $storage->get_metadata(self::ROOT_MAILBOX, self::ASYNC_KEY)) {
|
||||
$this->root_meta = $this->unserialize_metadata($meta[self::ROOT_MAILBOX][self::ASYNC_KEY]);
|
||||
}
|
||||
else {
|
||||
$this->root_meta = array();
|
||||
} else {
|
||||
$this->root_meta = [];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -286,7 +286,7 @@ class kolab_activesync extends rcube_plugin
|
|||
return $this->root_meta['DEVICE'];
|
||||
}
|
||||
|
||||
return array();
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -297,7 +297,7 @@ class kolab_activesync extends rcube_plugin
|
|||
public function folder_meta()
|
||||
{
|
||||
if (!isset($this->folder_meta)) {
|
||||
$this->folder_meta = array();
|
||||
$this->folder_meta = [];
|
||||
$storage = $this->rc->get_storage();
|
||||
|
||||
// get folders activesync config
|
||||
|
@ -332,17 +332,17 @@ class kolab_activesync extends rcube_plugin
|
|||
$metadata = $this->folder_meta();
|
||||
$metadata = $metadata[$name];
|
||||
|
||||
if ($flag) {
|
||||
if ($flag) {
|
||||
if (empty($metadata)) {
|
||||
$metadata = array();
|
||||
$metadata = [];
|
||||
}
|
||||
|
||||
if (empty($metadata['FOLDER'])) {
|
||||
$metadata['FOLDER'] = array();
|
||||
$metadata['FOLDER'] = [];
|
||||
}
|
||||
|
||||
if (empty($metadata['FOLDER'][$deviceid])) {
|
||||
$metadata['FOLDER'][$deviceid] = array();
|
||||
$metadata['FOLDER'][$deviceid] = [];
|
||||
}
|
||||
|
||||
// Z-Push uses:
|
||||
|
@ -376,8 +376,8 @@ class kolab_activesync extends rcube_plugin
|
|||
|
||||
$storage = $this->rc->get_storage();
|
||||
|
||||
return $storage->set_metadata($name, array(
|
||||
self::ASYNC_KEY => $this->serialize_metadata($metadata)));
|
||||
return $storage->set_metadata($name, [
|
||||
self::ASYNC_KEY => $this->serialize_metadata($metadata)]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -406,7 +406,7 @@ class kolab_activesync extends rcube_plugin
|
|||
|
||||
$metadata = $this->root_meta;
|
||||
$metadata['DEVICE'][$id] = $device;
|
||||
$metadata = array(self::ASYNC_KEY => $this->serialize_metadata($metadata));
|
||||
$metadata = [self::ASYNC_KEY => $this->serialize_metadata($metadata)];
|
||||
$storage = $this->rc->get_storage();
|
||||
|
||||
$result = $storage->set_metadata(self::ROOT_MAILBOX, $metadata);
|
||||
|
@ -445,7 +445,7 @@ class kolab_activesync extends rcube_plugin
|
|||
}
|
||||
|
||||
$metadata = $this->serialize_metadata($this->root_meta);
|
||||
$metadata = array(self::ASYNC_KEY => $metadata);
|
||||
$metadata = [self::ASYNC_KEY => $metadata];
|
||||
$storage = $this->rc->get_storage();
|
||||
|
||||
// update meta data
|
||||
|
@ -455,8 +455,9 @@ class kolab_activesync extends rcube_plugin
|
|||
// remove device annotation for every folder
|
||||
foreach ($this->folder_meta() as $folder => $meta) {
|
||||
// skip root folder (already handled above)
|
||||
if ($folder == self::ROOT_MAILBOX)
|
||||
if ($folder == self::ROOT_MAILBOX) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!empty($meta['FOLDER']) && isset($meta['FOLDER'][$id])) {
|
||||
unset($meta['FOLDER'][$id]);
|
||||
|
@ -470,7 +471,7 @@ class kolab_activesync extends rcube_plugin
|
|||
$meta = null;
|
||||
}
|
||||
|
||||
$metadata = array(self::ASYNC_KEY => $this->serialize_metadata($meta));
|
||||
$metadata = [self::ASYNC_KEY => $this->serialize_metadata($meta)];
|
||||
$res = $storage->set_metadata($folder, $metadata);
|
||||
|
||||
if ($res && $meta) {
|
||||
|
@ -484,8 +485,11 @@ class kolab_activesync extends rcube_plugin
|
|||
$table = $db->table_name('syncroton_device');
|
||||
|
||||
if (in_array($table, $db->list_tables())) {
|
||||
$db->query("DELETE FROM $table WHERE owner_id = ? AND deviceid = ?",
|
||||
$this->rc->user->ID, $id);
|
||||
$db->query(
|
||||
"DELETE FROM $table WHERE owner_id = ? AND deviceid = ?",
|
||||
$this->rc->user->ID,
|
||||
$id
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -505,12 +509,15 @@ class kolab_activesync extends rcube_plugin
|
|||
$table = $db->table_name('syncroton_device');
|
||||
|
||||
if (in_array($table, $db->list_tables())) {
|
||||
$fields = array('devicetype', 'acsversion', 'useragent', 'friendlyname', 'os',
|
||||
'oslanguage', 'phonenumber');
|
||||
$fields = ['devicetype', 'acsversion', 'useragent', 'friendlyname', 'os',
|
||||
'oslanguage', 'phonenumber'];
|
||||
|
||||
$result = $db->query("SELECT " . $db->array2list($fields, 'ident')
|
||||
$result = $db->query(
|
||||
"SELECT " . $db->array2list($fields, 'ident')
|
||||
. " FROM $table WHERE owner_id = ? AND id = ?",
|
||||
$this->rc->user->ID, $id);
|
||||
$this->rc->user->ID,
|
||||
$id
|
||||
);
|
||||
|
||||
if ($result && ($sql_arr = $db->fetch_assoc($result))) {
|
||||
return $sql_arr;
|
||||
|
|
|
@ -25,14 +25,14 @@
|
|||
|
||||
class kolab_activesync_ui
|
||||
{
|
||||
public $device = [];
|
||||
public $device = [];
|
||||
|
||||
private $rc;
|
||||
private $plugin;
|
||||
private $force_subscriptions = [];
|
||||
private $skin_path;
|
||||
|
||||
const SETUP_URL = 'https://kb.kolabenterprise.com/documentation/setting-up-an-activesync-client';
|
||||
public const SETUP_URL = 'https://kb.kolabenterprise.com/documentation/setting-up-an-activesync-client';
|
||||
|
||||
|
||||
public function __construct($plugin)
|
||||
|
@ -131,9 +131,8 @@ class kolab_activesync_ui
|
|||
|
||||
foreach ($this->plugin->list_folders() as $folder) {
|
||||
if (!empty($folder_types[$folder])) {
|
||||
list($type, ) = explode('.', $folder_types[$folder]);
|
||||
}
|
||||
else {
|
||||
[$type, ] = explode('.', $folder_types[$folder]);
|
||||
} else {
|
||||
$type = 'mail';
|
||||
}
|
||||
|
||||
|
@ -142,7 +141,7 @@ class kolab_activesync_ui
|
|||
|
||||
if ($device_force_subscriptions && array_key_exists($folder, $device_force_subscriptions)) {
|
||||
$subscribed[$folder] = intval($device_force_subscriptions[$folder]);
|
||||
} else if (!empty($folder_meta[$folder]['FOLDER'][$imei]['S'])) {
|
||||
} elseif (!empty($folder_meta[$folder]['FOLDER'][$imei]['S'])) {
|
||||
$subscribed[$folder] = intval($folder_meta[$folder]['FOLDER'][$imei]['S']);
|
||||
}
|
||||
}
|
||||
|
@ -161,8 +160,7 @@ class kolab_activesync_ui
|
|||
|
||||
if ($use_fieldsets) {
|
||||
$html .= html::tag('fieldset', 'subscriptionblock', html::tag('legend', $type, $label) . $table);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$html .= html::div('subscriptionblock', html::tag('h3', $type, $label) . $table);
|
||||
}
|
||||
}
|
||||
|
@ -177,19 +175,21 @@ class kolab_activesync_ui
|
|||
$alarms = ($attrib['type'] == 'event' || $attrib['type'] == 'task');
|
||||
|
||||
$table = new html_table(['cellspacing' => 0, 'class' => 'table-striped']);
|
||||
$table->add_header([
|
||||
$table->add_header(
|
||||
[
|
||||
'class' => 'subscription checkbox-cell',
|
||||
'title' => $this->plugin->gettext('synchronize'),
|
||||
'tabindex' => 0
|
||||
'tabindex' => 0,
|
||||
],
|
||||
!empty($attrib['syncicon']) ? html::img(['src' => $this->skin_path . $attrib['syncicon']]) : $this->plugin->gettext('synchronize')
|
||||
);
|
||||
|
||||
if ($alarms) {
|
||||
$table->add_header([
|
||||
$table->add_header(
|
||||
[
|
||||
'class' => 'alarm checkbox-cell',
|
||||
'title' => $this->plugin->gettext('withalarms'),
|
||||
'tabindex' => 0
|
||||
'tabindex' => 0,
|
||||
],
|
||||
!empty($attrib['alarmicon']) ? html::img(['src' => $this->skin_path . $attrib['alarmicon']]) : $this->plugin->gettext('withalarms')
|
||||
);
|
||||
|
@ -205,12 +205,12 @@ class kolab_activesync_ui
|
|||
$foldername = $origname = kolab_storage::object_prettyname($folder);
|
||||
|
||||
// find folder prefix to truncate (the same code as in kolab_addressbook plugin)
|
||||
for ($i = count($names)-1; $i >= 0; $i--) {
|
||||
if (strpos($foldername, $names[$i].' » ') === 0) {
|
||||
$length = strlen($names[$i].' » ');
|
||||
for ($i = count($names) - 1; $i >= 0; $i--) {
|
||||
if (strpos($foldername, $names[$i] . ' » ') === 0) {
|
||||
$length = strlen($names[$i] . ' » ');
|
||||
$prefix = substr($foldername, 0, $length);
|
||||
$count = count(explode(' » ', $prefix));
|
||||
$foldername = str_repeat(' ', $count-1) . '» ' . substr($foldername, $length);
|
||||
$foldername = str_repeat(' ', $count - 1) . '» ' . substr($foldername, $length);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -232,15 +232,17 @@ class kolab_activesync_ui
|
|||
|
||||
$table->add('subscription checkbox-cell', $checkbox_sync->show(
|
||||
!empty($subscribed[$folder]) ? $folder : null,
|
||||
['value' => $folder, 'id' => $folder_id, 'disabled' => $disabled]));
|
||||
['value' => $folder, 'id' => $folder_id, 'disabled' => $disabled]
|
||||
));
|
||||
|
||||
if ($alarms) {
|
||||
$table->add('alarm checkbox-cell', $checkbox_alarm->show(
|
||||
intval($subscribed[$folder] ?? 0) > 1 ? $folder : null,
|
||||
['value' => $folder, 'id' => $folder_id.'_alarm', 'disabled' => $disabled]));
|
||||
['value' => $folder, 'id' => $folder_id . '_alarm', 'disabled' => $disabled]
|
||||
));
|
||||
}
|
||||
|
||||
$table->add(join(' ', $classes), html::label($folder_id, $foldername));
|
||||
$table->add(implode(' ', $classes), html::label($folder_id, $foldername));
|
||||
}
|
||||
|
||||
return $table->show();
|
||||
|
@ -252,13 +254,13 @@ class kolab_activesync_ui
|
|||
$meta = $this->plugin->folder_meta();
|
||||
$folder_data = (array) ($meta[$folder_name] ? $meta[$folder_name]['FOLDER'] : null);
|
||||
|
||||
$table = new html_table(array('cellspacing' => 0, 'id' => 'folder-sync-options', 'class' => 'records-table'));
|
||||
$table = new html_table(['cellspacing' => 0, 'id' => 'folder-sync-options', 'class' => 'records-table']);
|
||||
|
||||
// table header
|
||||
$table->add_header(array('class' => 'device'), $this->plugin->gettext('devicealias'));
|
||||
$table->add_header(array('class' => 'subscription'), $this->plugin->gettext('synchronize'));
|
||||
$table->add_header(['class' => 'device'], $this->plugin->gettext('devicealias'));
|
||||
$table->add_header(['class' => 'subscription'], $this->plugin->gettext('synchronize'));
|
||||
if ($alarms) {
|
||||
$table->add_header(array('class' => 'alarm'), $this->plugin->gettext('withalarms'));
|
||||
$table->add_header(['class' => 'alarm'], $this->plugin->gettext('withalarms'));
|
||||
}
|
||||
|
||||
// table records
|
||||
|
@ -266,8 +268,8 @@ class kolab_activesync_ui
|
|||
$info = $this->plugin->device_info($device['ID']);
|
||||
$name = $id;
|
||||
$title = '';
|
||||
$checkbox = new html_checkbox(array('name' => "_subscriptions[$id]", 'value' => 1,
|
||||
'onchange' => 'return activesync_object.update_sync_data(this)'));
|
||||
$checkbox = new html_checkbox(['name' => "_subscriptions[$id]", 'value' => 1,
|
||||
'onchange' => 'return activesync_object.update_sync_data(this)']);
|
||||
|
||||
if (!empty($info)) {
|
||||
$_name = trim($info['friendlyname'] . ' ' . $info['os']);
|
||||
|
@ -281,14 +283,14 @@ class kolab_activesync_ui
|
|||
$disabled = $this->is_protected($folder_name, $device['TYPE']);
|
||||
|
||||
$table->add_row();
|
||||
$table->add(array('class' => 'device', 'title' => $title), $name);
|
||||
$table->add('subscription checkbox-cell', $checkbox->show(!empty($folder_data[$id]['S']) ? 1 : 0, array('disabled' => $disabled)));
|
||||
$table->add(['class' => 'device', 'title' => $title], $name);
|
||||
$table->add('subscription checkbox-cell', $checkbox->show(!empty($folder_data[$id]['S']) ? 1 : 0, ['disabled' => $disabled]));
|
||||
|
||||
if ($alarms) {
|
||||
$checkbox_alarm = new html_checkbox(array('name' => "_alarms[$id]", 'value' => 1,
|
||||
'onchange' => 'return activesync_object.update_sync_data(this)'));
|
||||
$checkbox_alarm = new html_checkbox(['name' => "_alarms[$id]", 'value' => 1,
|
||||
'onchange' => 'return activesync_object.update_sync_data(this)']);
|
||||
|
||||
$table->add('alarm checkbox-cell', $checkbox_alarm->show($folder_data[$id]['S'] > 1 ? 1 : 0, array('disabled' => $disabled)));
|
||||
$table->add('alarm checkbox-cell', $checkbox_alarm->show($folder_data[$id]['S'] > 1 ? 1 : 0, ['disabled' => $disabled]));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -298,13 +300,13 @@ class kolab_activesync_ui
|
|||
/**
|
||||
* Displays initial page (when no devices are registered)
|
||||
*/
|
||||
function init_message()
|
||||
public function init_message()
|
||||
{
|
||||
$this->plugin->load_config();
|
||||
|
||||
$this->rc->output->add_handlers(array(
|
||||
'initmessage' => array($this, 'init_message_content')
|
||||
));
|
||||
$this->rc->output->add_handlers([
|
||||
'initmessage' => [$this, 'init_message_content'],
|
||||
]);
|
||||
|
||||
$this->rc->output->send('kolab_activesync.configempty');
|
||||
}
|
||||
|
@ -312,11 +314,11 @@ class kolab_activesync_ui
|
|||
/**
|
||||
* Handler for initmessage template object
|
||||
*/
|
||||
function init_message_content()
|
||||
public function init_message_content()
|
||||
{
|
||||
$url = $this->rc->config->get('activesync_setup_url', self::SETUP_URL);
|
||||
$vars = array('url' => $url);
|
||||
$msg = $this->plugin->gettext(array('name' => 'nodevices', 'vars' => $vars));
|
||||
$vars = ['url' => $url];
|
||||
$msg = $this->plugin->gettext(['name' => 'nodevices', 'vars' => $vars]);
|
||||
|
||||
return $msg;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
<?php
|
||||
|
||||
$labels['task'] = 'Задачи';
|
||||
?>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
$labels['tabtitle'] = 'Activesync';
|
||||
$labels['devices'] = 'Устройства';
|
||||
$labels['devicealias'] = 'Име на устройство';
|
||||
|
@ -19,4 +20,3 @@ $labels['notsupported'] = 'Your server does not support metadata/annotations';
|
|||
$labels['devicedeleteconfirm'] = 'Наистина ли искате да изтриете конфигурацията за това устройство?';
|
||||
$labels['successfullydeleted'] = 'Конфигурацията за устройството беше премахната успешно';
|
||||
$labels['devicenotfound'] = 'Невъзможно прочитането на конфигурацията на устройството';
|
||||
?>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
$labels['contact'] = 'Contacts';
|
||||
$labels['event'] = 'Calendaris';
|
||||
$labels['task'] = 'Tasques';
|
||||
$labels['savingdata'] = 'S\'estan desant les dades...';
|
||||
?>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
$labels['tabtitle'] = 'Activesync';
|
||||
$labels['activesynctitle'] = 'Správa zařízení Avtivesync';
|
||||
$labels['devices'] = 'Zařízení';
|
||||
|
@ -30,4 +31,3 @@ $labels['os'] = 'Operační systém';
|
|||
$labels['oslanguage'] = 'Jazyk operačního systému';
|
||||
$labels['phonenumber'] = 'Telefonní číslo';
|
||||
$labels['arialabeldeviceframe'] = 'Nastavení synchronizace zařízení';
|
||||
?>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
$labels['tabtitle'] = 'Activesync';
|
||||
$labels['activesynctitle'] = 'Manage Activesync devices';
|
||||
$labels['devices'] = 'Enheder';
|
||||
|
@ -30,4 +31,3 @@ $labels['os'] = 'Operativsystem';
|
|||
$labels['oslanguage'] = 'Sprog for OS';
|
||||
$labels['phonenumber'] = 'Telefonnummer';
|
||||
$labels['arialabeldeviceframe'] = 'Device synchronization settings form';
|
||||
?>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
$labels['tabtitle'] = 'ActiveSync';
|
||||
$labels['activesynctitle'] = 'Verwalte ActiveSync-Geräte';
|
||||
$labels['devices'] = 'Geräte';
|
||||
|
@ -30,4 +31,3 @@ $labels['os'] = 'Betriebssystem';
|
|||
$labels['oslanguage'] = 'Betriebssystemsprache';
|
||||
$labels['phonenumber'] = 'Telefonnummer';
|
||||
$labels['arialabeldeviceframe'] = 'Formular für die Einstellungen zur Gerätesynchronisation';
|
||||
?>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
$labels['tabtitle'] = 'Activesync';
|
||||
$labels['activesynctitle'] = 'Verwalte ActiveSync-Geräte';
|
||||
$labels['devices'] = 'Geräte';
|
||||
|
@ -30,4 +31,3 @@ $labels['os'] = 'Betriebssystem';
|
|||
$labels['oslanguage'] = 'Betriebssystemsprache';
|
||||
$labels['phonenumber'] = 'Telefonnummer';
|
||||
$labels['arialabeldeviceframe'] = 'Formular für die Einstellungen zur Gerätesynchronisation';
|
||||
?>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
$labels['tabtitle'] = 'ActiveSync';
|
||||
$labels['activesynctitle'] = 'Verwalte ActiveSync-Geräte';
|
||||
$labels['devices'] = 'Geräte';
|
||||
|
@ -30,4 +31,3 @@ $labels['os'] = 'Betriebssystem';
|
|||
$labels['oslanguage'] = 'Betriebssystemsprache';
|
||||
$labels['phonenumber'] = 'Telefonnummer';
|
||||
$labels['arialabeldeviceframe'] = 'Formular für die Einstellungen zur Gerätesynchronisation';
|
||||
?>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
$labels['tabtitle'] = 'Activesync';
|
||||
$labels['activesynctitle'] = 'Διαχείριση συσκευών Activesync';
|
||||
$labels['devices'] = 'Συσκευές';
|
||||
|
@ -27,4 +28,3 @@ $labels['os'] = 'Λειτουργικό σύστημα';
|
|||
$labels['oslanguage'] = 'Γλώσσα λειτουργικού συστήματος';
|
||||
$labels['phonenumber'] = 'Αριθμός τηλεφώνου';
|
||||
$labels['arialabeldeviceframe'] = 'Ρυθμίσεις συγχρονισμού συσκευής από';
|
||||
?>
|
||||
|
|
|
@ -31,5 +31,3 @@ $labels['os'] = 'Operating system';
|
|||
$labels['oslanguage'] = 'OS language';
|
||||
$labels['phonenumber'] = 'Phone number';
|
||||
$labels['arialabeldeviceframe'] = 'Device synchronization settings form';
|
||||
|
||||
?>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
$labels['tabtitle'] = 'Activesync';
|
||||
$labels['activesynctitle'] = 'Administrar dispositivos Activesync';
|
||||
$labels['devices'] = 'Dispositivos';
|
||||
|
@ -30,4 +31,3 @@ $labels['os'] = 'Sistema operativo';
|
|||
$labels['oslanguage'] = 'Idioma del SO';
|
||||
$labels['phonenumber'] = 'Número de teléfono';
|
||||
$labels['arialabeldeviceframe'] = 'Formulario de configuración de sincronización del dispositivo';
|
||||
?>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
$labels['tabtitle'] = 'Activesync';
|
||||
$labels['activesynctitle'] = 'Administrar dispositivos ActiveSync';
|
||||
$labels['devices'] = 'Dispositivos';
|
||||
|
@ -30,4 +31,3 @@ $labels['os'] = 'Sistema operativo';
|
|||
$labels['oslanguage'] = 'Idioma del SI';
|
||||
$labels['phonenumber'] = 'Número de teléfono';
|
||||
$labels['arialabeldeviceframe'] = 'Formulario de configuración de sincronización de dispositivos';
|
||||
?>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
$labels['devices'] = 'Seadmed';
|
||||
$labels['devicealias'] = 'Seadme nimi';
|
||||
$labels['synchronize'] = 'Sünkrooni';
|
||||
|
@ -17,4 +18,3 @@ $labels['friendlyname'] = 'Inimsõbralik nimi';
|
|||
$labels['os'] = 'Operatsioonisüsteem';
|
||||
$labels['oslanguage'] = 'OS-i keel';
|
||||
$labels['phonenumber'] = 'Telefoninumber';
|
||||
?>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
$labels['tabtitle'] = 'Activesync';
|
||||
$labels['activesynctitle'] = 'Hallitse Activesync-laitteita';
|
||||
$labels['devices'] = 'Laitteet';
|
||||
|
@ -30,4 +31,3 @@ $labels['os'] = 'Käyttöjärjestelmä';
|
|||
$labels['oslanguage'] = 'Käyttöjärjestelmän kieli';
|
||||
$labels['phonenumber'] = 'Puhelinnumero';
|
||||
$labels['arialabeldeviceframe'] = 'Laitesynkronointiasetusten lomake';
|
||||
?>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
$labels['tabtitle'] = 'Activesync';
|
||||
$labels['activesynctitle'] = 'Gestion des périphériques Activesync';
|
||||
$labels['devices'] = 'Périphériques';
|
||||
|
@ -30,4 +31,3 @@ $labels['os'] = 'Système d\'exploitation';
|
|||
$labels['oslanguage'] = 'Langue de l\'OS';
|
||||
$labels['phonenumber'] = 'Numéro de téléphone';
|
||||
$labels['arialabeldeviceframe'] = 'Paramètres de synchronisation du périphérique';
|
||||
?>
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
<?php
|
||||
|
||||
$labels['event'] = 'Kalendari';
|
||||
?>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
$labels['tabtitle'] = 'Activesync';
|
||||
$labels['activesynctitle'] = 'Manage Activesync devices';
|
||||
$labels['devices'] = 'Készülékek';
|
||||
|
@ -29,4 +30,3 @@ $labels['os'] = 'Operációs rendszer';
|
|||
$labels['oslanguage'] = 'Készülék nyelve';
|
||||
$labels['phonenumber'] = 'Telefonszám';
|
||||
$labels['arialabeldeviceframe'] = 'Device synchronization settings form';
|
||||
?>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
$labels['tabtitle'] = 'Activesync';
|
||||
$labels['activesynctitle'] = 'Gestisci dispositivi Activesync';
|
||||
$labels['devices'] = 'Dispositivi';
|
||||
|
@ -29,4 +30,3 @@ $labels['os'] = 'Sistema operativo';
|
|||
$labels['oslanguage'] = 'Lingua SO';
|
||||
$labels['phonenumber'] = 'Numero di telefono';
|
||||
$labels['arialabeldeviceframe'] = 'Modulo impostazioni di sincronizzazione del dispositivo';
|
||||
?>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
$labels['tabtitle'] = 'アクティブシンク';
|
||||
$labels['activesynctitle'] = 'アクティブシンクデバイス管理';
|
||||
$labels['devices'] = '機器';
|
||||
|
@ -30,4 +31,3 @@ $labels['os'] = 'OS';
|
|||
$labels['oslanguage'] = 'OS言語';
|
||||
$labels['phonenumber'] = '電話番号';
|
||||
$labels['arialabeldeviceframe'] = 'デバイス同期設定元';
|
||||
?>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?php
|
||||
|
||||
$labels['event'] = '캘린더';
|
||||
$labels['savingdata'] = '자료 저장중...';
|
||||
?>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
$labels['devices'] = 'Ierīces';
|
||||
$labels['mail'] = 'E-pasts';
|
||||
$labels['event'] = 'Kalendāri';
|
||||
$labels['savingdata'] = 'Saglabājam...';
|
||||
?>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
$labels['tabtitle'] = 'Activesync';
|
||||
$labels['activesynctitle'] = 'Activesync-apparaten beheren';
|
||||
$labels['devices'] = 'Apparaten';
|
||||
|
@ -30,4 +31,3 @@ $labels['os'] = 'Besturingssysteem';
|
|||
$labels['oslanguage'] = 'Taal van besturingssysteem';
|
||||
$labels['phonenumber'] = 'Telefoonnummer';
|
||||
$labels['arialabeldeviceframe'] = 'Formulier met instellingen voor synchronisatie van apparaat';
|
||||
?>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?php
|
||||
|
||||
$labels['event'] = 'Kalendarze';
|
||||
$labels['task'] = 'Zadania';
|
||||
$labels['savingdata'] = 'Zapisuję dane...';
|
||||
?>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
$labels['tabtitle'] = 'ActiveSync';
|
||||
$labels['activesynctitle'] = 'Zarządzaj urządzeniami ActiveSync';
|
||||
$labels['devices'] = 'Urządzenia';
|
||||
|
@ -30,4 +31,3 @@ $labels['os'] = 'System operacyjny';
|
|||
$labels['oslanguage'] = 'Język systemu';
|
||||
$labels['phonenumber'] = 'Numer telefonu';
|
||||
$labels['arialabeldeviceframe'] = 'Formularz ustawień synchronizacji urządzenia';
|
||||
?>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
$labels['tabtitle'] = 'Activesync';
|
||||
$labels['devices'] = 'Dispositivos';
|
||||
$labels['devicealias'] = 'Nome do dispositivo';
|
||||
|
@ -20,4 +21,3 @@ $labels['devicedeleteconfirm'] = 'Você deseja realmente remover a configuraçã
|
|||
$labels['successfullydeleted'] = 'A configuração do dispositivo foi removida com sucesso';
|
||||
$labels['devicenotfound'] = 'Não foi possível ler a configuração do dispositivo';
|
||||
$labels['phonenumber'] = 'Telefone';
|
||||
?>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
$labels['tabtitle'] = 'Activesync';
|
||||
$labels['activesynctitle'] = 'Gerir dispositivos Activesync';
|
||||
$labels['devices'] = 'Dispostivos';
|
||||
|
@ -16,4 +17,3 @@ $labels['configuration'] = 'Configuração';
|
|||
$labels['deletedevice'] = 'Remover dispositivo';
|
||||
$labels['savingdata'] = 'A guardar os dados...';
|
||||
$labels['savingerror'] = 'Falha ao guardar as alterações.';
|
||||
?>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
$labels['tabtitle'] = 'Activesync';
|
||||
$labels['activesynctitle'] = 'Управление устройствами ActiveSync';
|
||||
$labels['devices'] = 'Устройства';
|
||||
|
@ -30,4 +31,3 @@ $labels['os'] = 'Операционная система';
|
|||
$labels['oslanguage'] = 'Язык ОС';
|
||||
$labels['phonenumber'] = 'Телефон';
|
||||
$labels['arialabeldeviceframe'] = 'Форма управления настройками синхронизации';
|
||||
?>
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
<?php
|
||||
|
||||
$labels['event'] = 'Kalendáre';
|
||||
?>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
$labels['mail'] = 'Email';
|
||||
$labels['contact'] = 'Kontakti';
|
||||
$labels['event'] = 'Koledarji';
|
||||
|
@ -6,4 +7,3 @@ $labels['task'] = 'Naloge';
|
|||
$labels['note'] = 'Zapiski';
|
||||
$labels['configuration'] = 'Nastavitve';
|
||||
$labels['savingdata'] = 'Shranjujem...';
|
||||
?>
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
|
||||
$labels['contact'] = 'Kontakter';
|
||||
$labels['event'] = 'Kalendrar';
|
||||
$labels['task'] = 'Uppgifter';
|
||||
$labels['note'] = 'Anteckningar';
|
||||
$labels['configuration'] = 'Konfiguration';
|
||||
$labels['savingdata'] = 'Sparar data ...';
|
||||
?>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
$labels['tabtitle'] = 'Activesync';
|
||||
$labels['activesynctitle'] = 'Hantera Activesync-enheter';
|
||||
$labels['devices'] = 'Enheter';
|
||||
|
@ -30,4 +31,3 @@ $labels['os'] = 'Operativsystem';
|
|||
$labels['oslanguage'] = 'OS-språk';
|
||||
$labels['phonenumber'] = 'Telefonnummer';
|
||||
$labels['arialabeldeviceframe'] = 'Inställningsformulär för enhetssynkronisering';
|
||||
?>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
$labels['tabtitle'] = 'Activesync';
|
||||
$labels['activesynctitle'] = 'จัดการอุปกรณ์ที่ใช้ Activesync';
|
||||
$labels['devices'] = 'อุปกรณ์';
|
||||
|
@ -27,4 +28,3 @@ $labels['os'] = 'ระบบปฎิบัติการ';
|
|||
$labels['oslanguage'] = 'ภาษาของระบบปฎิบัติการ';
|
||||
$labels['phonenumber'] = 'หมายเลขโทรศัพท์';
|
||||
$labels['arialabeldeviceframe'] = 'ฟอร์มการตั้งค่าการปรับปรุงให้สอดคล้องของอุปกรณ์';
|
||||
?>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
|
||||
$labels['mail'] = 'Пошта';
|
||||
$labels['event'] = 'Календарі';
|
||||
$labels['task'] = 'Задачі';
|
||||
$labels['note'] = 'Нотатки';
|
||||
$labels['savingdata'] = 'Збереження даних...';
|
||||
?>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
|
||||
$labels['activesynctitle'] = '管理Activesync设备';
|
||||
$labels['devices'] = '设备';
|
||||
$labels['mail'] = '邮件';
|
||||
$labels['note'] = '笔记';
|
||||
$labels['savingdata'] = '保存数据...';
|
||||
?>
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue