Projects
Kolab:16
roundcubemail-plugins-kolab
Log In
Username
Password
We truncated the diff of some files because they were too big. If you want to see the full diff for every file,
click here
.
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 88
View file
roundcubemail-plugins-kolab.spec
Changed
@@ -41,7 +41,7 @@ %global dash_rel_suffix %{?rc_rel_suffix:-%{rc_rel_suffix}} Name: roundcubemail-plugins-kolab -Version: 3.5.10 +Version: 3.5.11 Release: 1%{?dot_rel_suffix}%{?dist}
View file
debian.changelog
Changed
@@ -1,3 +1,9 @@ +roundcubemail-plugins-kolab (1:3.5.11-0~kolab1) unstable; urgency=low + + * Release version 3.5.11 + + -- Jeroen van Meeuwen <vanmeeuwen@apheleia-it.ch> Fri, 14 Jan 2022 11:11:11 +0200 + roundcubemail-plugins-kolab (1:3.5.10-0~kolab1) unstable; urgency=low * Release version 3.5.10
View file
roundcubemail-plugins-kolab-3.5.10.tar.gz/plugins/calendar/calendar.php -> roundcubemail-plugins-kolab-3.5.11.tar.gz/plugins/calendar/calendar.php
Changed
@@ -1239,23 +1239,31 @@ $noreply = intval($noreply) || $status == 'needs-action' || $itip_sending === 0; $reload = $event['calendar'] != $ev['calendar'] || !empty($event['recurrence']) ? 2 : 1; $emails = $this->get_user_emails(); + $ownedResourceEmails = $this->owned_resources_emails(); $organizer = null; + $resourceConfirmation = false; foreach ($event['attendees'] as $i => $attendee) { if ($attendee['role'] == 'ORGANIZER') { $organizer = $attendee; } - else if (!empty($attendee['email']) && in_array(strtolower($attendee['email']), $emails)) { + else if (!empty($attendee['email']) && in_array_nocase($attendee['email'], $emails)) { $reply_sender = $attendee['email']; } + else if (!empty($attendee['cutype']) && $attendee['cutype'] == 'RESOURCE' && !empty($attendee['email']) && in_array_nocase($attendee['email'], $ownedResourceEmails)) { + $resourceConfirmation = true; + // Note on behalf of which resource this update is going to be sent out + $event['_resource'] = $attendee['email']; + } } if (!$noreply) { $itip = $this->load_itip(); $itip->set_sender_email($reply_sender); $event['thisandfuture'] = $event['_savemode'] == 'future'; + $bodytextprefix = $resourceConfirmation ? 'itipmailbodyresource' : 'itipmailbody'; - if ($organizer && $itip->send_itip_message($event, 'REPLY', $organizer, 'itipsubject' . $status, 'itipmailbody' . $status)) { + if ($organizer && $itip->send_itip_message($event, 'REPLY', $organizer, 'itipsubject' . $status, $bodytextprefix . $status)) { $mailto = !empty($organizer['name']) ? $organizer['name'] : $organizer['email']; $msg = $this->gettext(['name' => 'sentresponseto', 'vars' => ['mailto' => $mailto]]); @@ -2006,10 +2014,12 @@ } $identity['emails'][] = $this->rc->user->get_username(); + $identity['ownedResources'] = $this->owned_resources_emails(); $settings['identity'] = [ 'name' => $identity['name'], 'email' => strtolower($identity['email']), - 'emails' => ';' . strtolower(join(';', $identity['emails'])) + 'emails' => ';' . strtolower(join(';', $identity['emails'])), + 'ownedResources' => ';' . strtolower(join(';', $identity['ownedResources'])) ]; } @@ -2339,7 +2349,7 @@ } $attachments = []; - $eventid = 'cal-' . (!empty($event['id']) ? $event['id'] : 'new-event'); + $eventid = 'cal-' . (!empty($event['id']) ? $event['id'] : 'new'); if (!empty($_SESSION[self::SESSION_KEY]) && $_SESSION[self::SESSION_KEY]['id'] == $eventid) { if (!empty($_SESSION[self::SESSION_KEY]['attachments'])) { @@ -2868,6 +2878,21 @@ exit; } + /** + * List email addressed of owned resources + */ + private function owned_resources_emails() + { + $results = []; + if ($directory = $this->resources_directory()) { + foreach ($directory->load_resources($_SESSION['kolab_dn'], 5000, 'owner') as $rec) { + $results[] = $rec['email']; + } + } + return $results; + } + + /**** Event invitation plugin hooks ****/ /** @@ -3149,10 +3174,16 @@ */ private function mail_agenda_event_row($event, $class = '') { - $time = !empty($event['allday']) ? $this->gettext('all-day') : - $this->rc->format_date($event['start'], $this->rc->config->get('time_format')) - . ' - ' . - $this->rc->format_date($event['end'], $this->rc->config->get('time_format')); + if (!empty($event['allday'])) { + $time = $this->gettext('all-day'); + } + else { + $start = is_object($event['start']) ? clone $event['start'] : $event['start']; + $end = is_object($event['end']) ? clone $event['end'] : $event['end']; + + $time = $this->rc->format_date($start, $this->rc->config->get('time_format')) + . ' - ' . $this->rc->format_date($end, $this->rc->config->get('time_format')); + } return html::div(rtrim('event-row ' . ($class ?: $event['className'])), html::span('event-date', $time) @@ -3217,7 +3248,7 @@ // get prepared inline UI for this event object if ($ical_objects->method) { $append = ''; - $date_str = $this->rc->format_date($event['start'], $this->rc->config->get('date_format'), empty($event['start']->_dateonly)); + $date_str = $this->rc->format_date(clone $event['start'], $this->rc->config->get('date_format'), empty($event['start']->_dateonly)); $date = new DateTime($event['start']->format('Y-m-d') . ' 12:00:00', new DateTimeZone('UTC')); // prepare a small agenda preview to be filled with actual event data on async request @@ -3406,39 +3437,38 @@ // only update attendee status if ($event['_method'] == 'REPLY') { - // try to identify the attendee using the email sender address - $existing_attendee = -1; - $existing_attendee_emails = []; - - foreach ($existing['attendees'] as $i => $attendee) { - $existing_attendee_emails[] = $attendee['email']; - if ($this->itip->compare_email($attendee['email'], $event['_sender'], $event['_sender_utf'])) { - $existing_attendee = $i; - } - } + $existing_attendee_index = -1; $event_attendee = null; $update_attendees = []; - foreach ($event['attendees'] as $attendee) { - if ($this->itip->compare_email($attendee['email'], $event['_sender'], $event['_sender_utf'])) { - $event_attendee = $attendee; - $update_attendees[] = $attendee; - $metadata['fallback'] = $attendee['status']; - $metadata['attendee'] = $attendee['email']; - $metadata['rsvp'] = !empty($attendee['rsvp']) || $attendee['role'] != 'NON-PARTICIPANT'; - - if ($attendee['status'] != 'DELEGATED') { - break; + if ($attendee = $this->itip->find_reply_attendee($event)) { + $event_attendee = $attendee; + $update_attendees[] = $attendee; + $metadata['fallback'] = $attendee['status']; + $metadata['attendee'] = $attendee['email']; + $metadata['rsvp'] = !empty($attendee['rsvp']) || $attendee['role'] != 'NON-PARTICIPANT'; + + $existing_attendee_emails = []; + + // Find the attendee to update + foreach ($existing['attendees'] as $i => $existing_attendee) { + $existing_attendee_emails[] = $existing_attendee['email']; + if ($this->itip->compare_email($existing_attendee['email'], $attendee['email'])) { + $existing_attendee_index = $i; } } - // also copy delegate attendee - else if (!empty($attendee['delegated-from']) - && $this->itip->compare_email($attendee['delegated-from'], $event['_sender'], $event['_sender_utf']) - ) { - $update_attendees[] = $attendee; - if (!in_array_nocase($attendee['email'], $existing_attendee_emails)) { - $existing['attendees'][] = $attendee; + + if ($attendee['status'] == 'DELEGATED') { + //Also find and copy the delegatee + $delegatee_email = $attendee['email']; + $delegatees = array_filter($event['attendees'], function($attendee) use ($delegatee_email){ return $attendee['role'] != 'ORGANIZER' && $this->itip->compare_email($attendee['delegated-from'], $delegatee_email); }); + + if ($delegatee = $this->itip->find_attendee_by_email($event['attendees'], 'delegated-from', $attendee['email'])) { + $update_attendees[] = $delegatee; + if (!in_array_nocase($delegatee['email'], $existing_attendee_emails)) { + $existing['attendees'][] = $delegated_attendee; + } } } } @@ -3456,29 +3486,9 @@ } } - // Accept sender as a new participant (different email in From: and the iTip) - // Use ATTENDEE entry from the iTip with replaced email address - if (!$event_attendee) { - // remove the organizer - $itip_attendees = array_filter( - $event['attendees'], - function($item) { return $item['role'] != 'ORGANIZER'; } - ); - - // there must be only one attendee - if (is_array($itip_attendees) && count($itip_attendees) == 1) { - $event_attendee = $itip_attendees[key($itip_attendees)]; - $event_attendee['email'] = $event['_sender']; - $update_attendees[] = $event_attendee; - $metadata['fallback'] = $event_attendee['status']; - $metadata['attendee'] = $event_attendee['email']; - $metadata['rsvp'] = !empty($event_attendee['rsvp']) || $event_attendee['role'] != 'NON-PARTICIPANT'; - } - } - // found matching attendee entry in both existing and new events
View file
roundcubemail-plugins-kolab-3.5.10.tar.gz/plugins/calendar/calendar_ui.js -> roundcubemail-plugins-kolab-3.5.11.tar.gz/plugins/calendar/calendar_ui.js
Changed
@@ -399,7 +399,7 @@ $('#event-alarm').show().find('.event-text').html(Q(event.alarms_text).replace(',', ',<br>')); if (calendar.name) $('#event-calendar').show().find('.event-text').html(Q(calendar.name)).addClass('cal-'+calendar.id); - if (event.categories) + if (event.categories && String(event.categories).length) $('#event-category').show().find('.event-text').text(event.categories).addClass('cat-'+String(event.categories).toLowerCase().replace(rcmail.identifier_expr, '')); if (event.free_busy) $('#event-free-busy').show().find('.event-text').text(rcmail.gettext(event.free_busy, 'calendar')); @@ -460,7 +460,7 @@ for (var j=0; j < num_attendees; j++) { data = event.attendees[j]; if (data.email) { - if (data.role != 'ORGANIZER' && settings.identity.emails.indexOf(';'+data.email) >= 0) { + if (data.role != 'ORGANIZER' && is_this_me(data.email)) { mystatus = (data.status || 'UNKNOWN').toLowerCase(); if (data.status == 'NEEDS-ACTION' || data.status == 'TENTATIVE' || data.rsvp) rsvp = mystatus; @@ -2380,6 +2380,14 @@ add_attendee($.extend({ role:'REQ-PARTICIPANT', status:'NEEDS-ACTION', cutype:'RESOURCE' }, resource)); } + var is_this_me = function(email) + { + if (settings.identity.emails.indexOf(';'+email) >= 0 || settings.identity.ownedResources.indexOf(';'+email) >= 0) { + return true; + } + return false; + }; + // when the user accepts or declines an event invitation var event_rsvp = function(response, delegate, replymode, event) { @@ -2414,7 +2422,8 @@ attendees = []; for (var data, i=0; i < me.selected_event.attendees.length; i++) { data = me.selected_event.attendees[i]; - if (settings.identity.emails.indexOf(';'+String(data.email).toLowerCase()) >= 0) { + //FIXME this can only work if there is a single resource per invitation + if (is_this_me(String(data.email).toLowerCase())) { data.status = response.toUpperCase(); data.rsvp = 0; // unset RSVP flag
View file
roundcubemail-plugins-kolab-3.5.10.tar.gz/plugins/calendar/composer.json -> roundcubemail-plugins-kolab-3.5.11.tar.gz/plugins/calendar/composer.json
Changed
@@ -4,7 +4,7 @@ "description": "Calendar plugin", "homepage": "https://git.kolab.org/diffusion/RPK/", "license": "AGPLv3", - "version": "3.5.10", + "version": "3.5.11", "authors": [ { "name": "Thomas Bruederli",
View file
roundcubemail-plugins-kolab-3.5.10.tar.gz/plugins/calendar/drivers/ldap/resources_driver_ldap.php -> roundcubemail-plugins-kolab-3.5.11.tar.gz/plugins/calendar/drivers/ldap/resources_driver_ldap.php
Changed
@@ -41,12 +41,13 @@ /** * Fetch resource objects to be displayed for booking * - * @param string $query Search query (optional) - * @param int $num Max size of the result + * @param string $query Search query (optional) + * @param int $num Max size of the result + * @param string $searchField Field to search with query * * @return array List of resource records available for booking */ - public function load_resources($query = null, $num = 5000) + public function load_resources($query = null, $num = 5000, $searchField = '*') { if (!($ldap = $this->connect())) { return []; @@ -56,7 +57,7 @@ $ldap->set_pagesize($num); if (isset($query)) { - $results = $ldap->search('*', $query, 0, true, true); + $results = $ldap->search($searchField, $query, 0, true, true); } else { $results = $ldap->list_records();
View file
roundcubemail-plugins-kolab-3.5.10.tar.gz/plugins/calendar/localization/en_US.inc -> roundcubemail-plugins-kolab-3.5.11.tar.gz/plugins/calendar/localization/en_US.inc
Changed
@@ -207,6 +207,10 @@ $labels['itipmailbodydelegated'] = "\$sender has delegated the participation in the following event:\n\n*\$title*\n\nWhen: \$date"; $labels['itipmailbodydelegatedto'] = "\$sender has delegated the participation in the following event to you:\n\n*\$title*\n\nWhen: \$date"; +$labels['itipmailbodyresourceaccepted'] = "\$sender has accepted the following resource booking:\n\n*\$title*\n\nWhen: \$date\n\nInvitees: \$attendees"; +$labels['itipmailbodyresourcetentative'] = "\$sender has tentatively accepted the following resource booking:\n\n*\$title*\n\nWhen: \$date\n\nInvitees: \$attendees"; +$labels['itipmailbodyresourcedeclined'] = "\$sender has declined the the following resource booking:\n\n*\$title*\n\nWhen: \$date\n\nInvitees: \$attendees"; + $labels['itipdeclineevent'] = 'Do you want to decline your invitation to this event?'; $labels['declinedeleteconfirm'] = 'Do you also want to delete this declined event from your calendar?'; $labels['itipcomment'] = 'Invitation/notification comment';
View file
roundcubemail-plugins-kolab-3.5.10.tar.gz/plugins/kolab_2fa/composer.json -> roundcubemail-plugins-kolab-3.5.11.tar.gz/plugins/kolab_2fa/composer.json
Changed
@@ -4,7 +4,7 @@ "description": "Kolab 2-Factor Authentication", "homepage": "https://git.kolab.org/diffusion/RPK/", "license": "AGPLv3", - "version": "3.5.8", + "version": "3.5.11", "authors": [ { "name": "Thomas Bruederli",
View file
roundcubemail-plugins-kolab-3.5.10.tar.gz/plugins/kolab_2fa/kolab2fa.js -> roundcubemail-plugins-kolab-3.5.11.tar.gz/plugins/kolab_2fa/kolab2fa.js
Changed
@@ -128,11 +128,6 @@ * Remove the given factor from the account */ function remove_factor(id) { - if (rcmail.env.kolab_2fa_factors[id]) { - rcmail.env.kolab_2fa_factors[id].active = false; - } - render(); - var lock = rcmail.set_busy(true, 'saving'); rcmail.http_post('plugin.kolab-2fa-save', { _method: id, _data: 'false' }, lock); } @@ -184,7 +179,7 @@ function require_high_security(func, exclude) { // request 2nd factor auth - if (!rcmail.env.session_secured || rcmail.env.session_secured < time() - 120) { + if (rcmail.env.session_secured !== true && rcmail.env.session_secured < time() - 180) { var method, name; // find an active factor @@ -327,7 +322,7 @@ // callback for save failure rcmail.addEventListener('plugin.reset_form', function(method) { - if (rcmail.env.kolab_2fa_factors[method]) { + if (method && rcmail.env.kolab_2fa_factors[method]) { rcmail.env.kolab_2fa_factors[method].active = false; }
View file
roundcubemail-plugins-kolab-3.5.10.tar.gz/plugins/kolab_2fa/kolab_2fa.php -> roundcubemail-plugins-kolab-3.5.11.tar.gz/plugins/kolab_2fa/kolab_2fa.php
Changed
@@ -422,10 +422,7 @@ $this->include_script('kolab2fa.js'); $this->include_stylesheet($this->local_skin_path() . '/kolab2fa.css'); - if ($this->check_secure_mode()) { - $this->api->output->set_env('session_secured', $_SESSION['kolab_2fa_secure_mode']); - } - + $this->api->output->set_env('session_secured', $this->check_secure_mode()); $this->api->output->add_label('save','cancel'); $this->api->output->set_pagetitle($this->gettext('settingstitle')); $this->api->output->send('kolab_2fa.config'); @@ -671,7 +668,7 @@ } else if ($errors) { $this->api->output->show_message($this->gettext('factorsaveerror'), 'error'); - $this->api->output->command('plugin.reset_form', $method); + $this->api->output->command('plugin.reset_form', $data !== false ? $method : null); } $this->api->output->send(); @@ -779,12 +776,20 @@ } /** - * + * Check whether the session is secured with 2FA (excluding the logon) */ protected function check_secure_mode() { - $valid = ($_SESSION['kolab_2fa_secure_mode'] && $_SESSION['kolab_2fa_secure_mode'] > time() - 180); - return $valid; - } + // Allow admins that used kolab_auth's "login as" feature to act without + // being asked for the user's second factor + if (!empty($_SESSION['kolab_auth_admin']) && !empty($_SESSION['kolab_auth_password'])) { + return true; + } -} \ No newline at end of file + if ($_SESSION['kolab_2fa_secure_mode'] && $_SESSION['kolab_2fa_secure_mode'] > time() - 180) { + return $_SESSION['kolab_2fa_secure_mode']; + } + + return false; + } +}
View file
roundcubemail-plugins-kolab-3.5.10.tar.gz/plugins/kolab_delegation/composer.json -> roundcubemail-plugins-kolab-3.5.11.tar.gz/plugins/kolab_delegation/composer.json
Changed
@@ -4,7 +4,7 @@ "description": "Kolab delegation feature", "homepage": "https://git.kolab.org/diffusion/RPK/", "license": "AGPLv3", - "version": "3.5.6", + "version": "3.5.11", "authors": [ { "name": "Aleksander Machniak",
View file
roundcubemail-plugins-kolab-3.5.10.tar.gz/plugins/kolab_delegation/kolab_delegation_engine.php -> roundcubemail-plugins-kolab-3.5.11.tar.gz/plugins/kolab_delegation/kolab_delegation_engine.php
Changed
@@ -378,6 +378,8 @@ // Definition of read and write ACL $right_types = $this->right_types(); + $delegate_lc = strtolower($delegate); + foreach ($folders as $folder) { // get only folders in personal namespace if ($storage->folder_namespace($folder) != 'personal') { @@ -395,8 +397,8 @@ // in edit mode, get folder ACL if ($delegate) { // @TODO: cache ACL - $acl = $storage->get_acl($folder); - if ($acl = $acl[$delegate]) { + $imap_acl = $storage->get_acl($folder); + if (!empty($imap_acl) && (($acl = $imap_acl[$delegate]) || ($acl = $imap_acl[$delegate_lc]))) { if ($this->acl_compare($acl, $right_types[self::ACL_WRITE])) { $rights = self::ACL_WRITE; }
View file
roundcubemail-plugins-kolab-3.5.10.tar.gz/plugins/libcalendaring/composer.json -> roundcubemail-plugins-kolab-3.5.11.tar.gz/plugins/libcalendaring/composer.json
Changed
@@ -4,7 +4,7 @@ "description": "Library providing common functions for calendaring plugins", "homepage": "https://git.kolab.org/diffusion/RPK/", "license": "AGPLv3", - "version": "3.5.10", + "version": "3.5.11", "authors": [ { "name": "Thomas Bruederli",
View file
roundcubemail-plugins-kolab-3.5.10.tar.gz/plugins/libcalendaring/lib/libcalendaring_itip.php -> roundcubemail-plugins-kolab-3.5.11.tar.gz/plugins/libcalendaring/lib/libcalendaring_itip.php
Changed
@@ -136,7 +136,7 @@ 'name' => $bodytext, 'vars' => array( 'title' => $event['title'], - 'date' => $this->lib->event_date_text($event, true) . $recurrence_info, + 'date' => $this->lib->event_date_text($event) . $recurrence_info, 'attendees' => join(",\n ", $attendees_list), 'sender' => $this->sender['name'], 'organizer' => $this->sender['name'], @@ -219,6 +219,11 @@ if ($attendee['role'] == 'ORGANIZER') { $reply_attendees[] = $attendee; } + // we accept on behalf of a resource + else if (strcasecmp($attendee['email'], $event['_resource']) == 0) { + $replying_attendee = $attendee; + $replying_attendee['sent-by'] = 'mailto:' . $from_utf; + } else if (strcasecmp($attendee['email'], $from) == 0 || strcasecmp($attendee['email'], $from_utf) == 0) { $replying_attendee = $attendee; if ($attendee['status'] != 'DELEGATED') { @@ -628,30 +633,13 @@ if ($method == 'REPLY') { $title = $this->gettext('itipreply'); - foreach ($event['attendees'] as $attendee) { - if (!empty($attendee['email']) && $attendee['role'] != 'ORGANIZER') { - if (empty($event['_sender']) || self::compare_email($attendee['email'], $event['_sender'], $event['_sender_utf'])) { - $metadata['attendee'] = $attendee['email']; - $rsvp_status = strtoupper($attendee['status']); - if ($attendee['delegated-to']) { - $metadata['delegated-to'] = $attendee['delegated-to']; - } - break; - } - } - } - - // It may happen that sender's address is different in From: and the attached iTip - // In such case use the ATTENDEE entry with the address from From: header - if (empty($metadata['attendee']) && !empty($event['_sender'])) { - // remove the organizer - $itip_attendees = array_filter($event['attendees'], function($item) { return $item['role'] != 'ORGANIZER'; }); + $attendee = self::find_reply_attendee($event); - // there must be only one attendee - if (is_array($itip_attendees) && count($itip_attendees) == 1) { - $event_attendee = $itip_attendees[key($itip_attendees)]; - $metadata['attendee'] = $event['_sender']; - $rsvp_status = strtoupper($event_attendee['status']); + if ($attendee) { + $metadata['attendee'] = $attendee['email']; + $rsvp_status = strtoupper($attendee['status']); + if ($attendee['delegated-to']) { + $metadata['delegated-to'] = $attendee['delegated-to']; } } @@ -1008,4 +996,50 @@ return $v1 || $v2; } + + /** + * Find an attendee that is not the organizer and has an email matching $email_field + */ + public function find_attendee_by_email($attendees, $email_field, $email, $email_utf = null) { + foreach ($attendees as $_attendee) { + if ($attendee['role'] == 'ORGANIZER') { + continue; + } + if (!empty($attendee[$email_field]) && self::compare_email($attendee[$email_field], $email, $email_utf)) { + return $attendee; + } + } + return null; + } + + /** + * Find the replying attendee in a REPLY + */ + public static function find_reply_attendee($event) { + // remove the organizer + $itip_attendees = array_filter($event['attendees'], function($item) { return $item['role'] != 'ORGANIZER' && !empty($item['email']); }); + $attendee = null; + + // According to rfc there should only be one attendee for a REPLY + if (count($itip_attendees) == 1) { + return array_pop($itip_attendees); + } + + // If we don't have anything to match by, pick the first and hope for the best. + if (empty($event['_sender'])) { + return array_shift($itip_attendees); + } + + // try to match by sent-by + if ($attendee = self::find_attendee_by_email($itip_attendees, 'sent-by', $event['_sender'], $event['_sender_utf'])) { + return $attendee; + } + + // try to match by email + if ($attendee = self::find_attendee_by_email($itip_attendees, 'email', $event['_sender'], $event['_sender_utf'])) { + return $attendee; + } + + return null; + } }
View file
roundcubemail-plugins-kolab-3.5.10.tar.gz/plugins/libcalendaring/libcalendaring.php -> roundcubemail-plugins-kolab-3.5.11.tar.gz/plugins/libcalendaring/libcalendaring.php
Changed
@@ -288,19 +288,43 @@ /** * Compose a date string for the given event */ - public function event_date_text($event, $tzinfo = false) + public function event_date_text($event) { $fromto = '--'; $is_task = !empty($event['_type']) && $event['_type'] == 'task'; + $this->date_format_defaults(); + + $date_format = self::to_php_date_format($this->rc->config->get('calendar_date_format', $this->defaults['calendar_date_format'])); + $time_format = self::to_php_date_format($this->rc->config->get('calendar_time_format', $this->defaults['calendar_time_format'])); + + $getTimezone = function ($date) { + if ($newTz = $date->getTimezone()) { + return $newTz->getName(); + } + + return ''; + }; + + $formatDate = function ($date, $format) use ($getTimezone) { + // This is a workaround for the rcmail::format_date() which does not play nice with timezone + $tz = $this->rc->config->get('timezone'); + if ($dateTz = $getTimezone($date)) { + $this->rc->config->set('timezone', $dateTz); + } + $result = $this->rc->format_date($date, $format); + $this->rc->config->set('timezone', $tz); + + return $result; + }; + // handle task objects if ($is_task && !empty($event['due']) && is_object($event['due'])) { - $date_format = !empty($event['due']->_dateonly) ? self::to_php_date_format($this->rc->config->get('calendar_date_format', $this->defaults['calendar_date_format'])) : null; - $fromto = $this->rc->format_date($event['due'], $date_format, false); + $fromto = $formatDate($event['due'], !empty($event['due']->_dateonly) ? $date_format : null); // add timezone information - if ($fromto && $tzinfo && ($tzname = $this->timezone->getName())) { - $fromto .= ' (' . strtr($tzname, '_', ' ') . ')'; + if ($fromto && empty($event['due']->_dateonly) && ($tz = $getTimezone($event['due']))) { + $fromto .= ' (' . strtr($tz, '_', ' ') . ')'; } return $fromto; @@ -311,29 +335,24 @@ return $fromto; } - $duration = $event['start']->diff($event['end'])->format('s'); - - $this->date_format_defaults(); - $date_format = self::to_php_date_format($this->rc->config->get('calendar_date_format', $this->defaults['calendar_date_format'])); - $time_format = self::to_php_date_format($this->rc->config->get('calendar_time_format', $this->defaults['calendar_time_format'])); - if ($event['allday']) { - $fromto = $this->rc->format_date($event['start'], $date_format, false); - if (($todate = $this->rc->format_date($event['end'], $date_format, false)) != $fromto) + $fromto = $formatDate($event['start'], $date_format); + if (($todate = $formatDate($event['end'], $date_format)) != $fromto) { $fromto .= ' - ' . $todate; + } } - else if ($duration < 86400 && $event['start']->format('d') == $event['end']->format('d')) { - $fromto = $this->rc->format_date($event['start'], $date_format) . ' ' . $this->rc->format_date($event['start'], $time_format) . - ' - ' . $this->rc->format_date($event['end'], $time_format); + else if ($event['start']->format('Ymd') === $event['end']->format('Ymd')) { + $fromto = $formatDate($event['start'], $date_format) . ' ' . $formatDate($event['start'], $time_format) . + ' - ' . $formatDate($event['end'], $time_format); } else { - $fromto = $this->rc->format_date($event['start'], $date_format) . ' ' . $this->rc->format_date($event['start'], $time_format) . - ' - ' . $this->rc->format_date($event['end'], $date_format) . ' ' . $this->rc->format_date($event['end'], $time_format); + $fromto = $formatDate($event['start'], $date_format) . ' ' . $formatDate($event['start'], $time_format) . + ' - ' . $formatDate($event['end'], $date_format) . ' ' . $formatDate($event['end'], $time_format); } // add timezone information - if ($tzinfo && ($tzname = $this->timezone->getName())) { - $fromto .= ' (' . strtr($tzname, '_', ' ') . ')'; + if ($fromto && empty($event['allday']) && ($tz = $getTimezone($event['start']))) { + $fromto .= ' (' . strtr($tz, '_', ' ') . ')'; } return $fromto;
View file
roundcubemail-plugins-kolab-3.5.10.tar.gz/plugins/libkolab/composer.json -> roundcubemail-plugins-kolab-3.5.11.tar.gz/plugins/libkolab/composer.json
Changed
@@ -4,7 +4,7 @@ "description": "Plugin to setup a basic environment for the interaction with a Kolab server.", "homepage": "https://git.kolab.org/diffusion/RPK/", "license": "AGPLv3", - "version": "3.5.10", + "version": "3.5.11", "authors": [ { "name": "Thomas Bruederli",
View file
roundcubemail-plugins-kolab-3.5.10.tar.gz/plugins/libkolab/lib/kolab_attachments_handler.php -> roundcubemail-plugins-kolab-3.5.11.tar.gz/plugins/libkolab/lib/kolab_attachments_handler.php
Changed
@@ -114,8 +114,9 @@ $this->rc->upload_progress(); } - $recid = $id_prefix . rcube_utils::get_input_value('_id', rcube_utils::INPUT_GPC); + $id = rcube_utils::get_input_value('_id', rcube_utils::INPUT_GPC); $uploadid = rcube_utils::get_input_value('_uploadid', rcube_utils::INPUT_GPC); + $recid = $id_prefix . ($id ?: 'new'); if (empty($_SESSION[$session_key]) || $_SESSION[$session_key]['id'] != $recid) { $_SESSION[$session_key] = array();
View file
roundcubemail-plugins-kolab.dsc
Changed
@@ -2,7 +2,7 @@ Source: roundcubemail-plugins-kolab Binary: roundcubemail-plugins-kolab Architecture: all -Version: 1:3.5.10-0~kolab1 +Version: 1:3.5.11-0~kolab1 Maintainer: Jeroen van Meeuwen <vanmeeuwen@kolabsys.com> Uploaders: Jeroen van Meeuwen <vanmeeuwen@kolabsys.com> Standards-Version: 3.9.3 @@ -37,5 +37,5 @@ roundcubemail-plugin-tinymce-config deb web extra roundcubemail-plugin-wap-client deb web extra Files: - 00000000000000000000000000000000 0 roundcubemail-plugins-kolab-3.5.10.tar.gz + 00000000000000000000000000000000 0 roundcubemail-plugins-kolab-3.5.11.tar.gz 00000000000000000000000000000000 0 debian.tar.gz
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.